changeset 8003:f686c8e3c8e0

Merge
author ewendeli
date Mon, 25 Feb 2013 08:44:00 +0100
parents 6f9b3e216b01 f7fb3de623ba
children e3cac5962e32
files src/share/classes/com/sun/java/util/jar/pack/BandStructure.java src/share/classes/java/util/jar/JarFile.java src/share/classes/java/util/logging/LogManager.java src/share/classes/sun/security/util/KeyLength.java src/share/native/com/sun/java/util/jar/pack/bands.cpp src/share/native/com/sun/java/util/jar/pack/bands.h src/share/native/com/sun/java/util/jar/pack/unpack.cpp
diffstat 107 files changed, 3670 insertions(+), 1247 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/bin/jli_util.h	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/bin/jli_util.h	Mon Feb 25 08:44:00 2013 +0100
@@ -66,7 +66,7 @@
 #include <io.h>
 #define JLI_StrCaseCmp(p1, p2)          stricmp((p1), (p2))
 #define JLI_StrNCaseCmp(p1, p2, p3)     strnicmp((p1), (p2), (p3))
-#define JLI_Snprintf                    _snprintf
+int  JLI_Snprintf(char *buffer, size_t size, const char *format, ...);
 void JLI_CmdToArgs(char *cmdline);
 #define JLI_Lseek                       _lseeki64
 #else  /* NIXES */
--- a/src/share/bin/parse_manifest.c	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/bin/parse_manifest.c	Mon Feb 25 08:44:00 2013 +0100
@@ -569,9 +569,9 @@
 #ifdef O_BINARY
         | O_BINARY /* use binary mode on windows */
 #endif
-        )) == -1)
+        )) == -1) {
         return (-1);
-
+    }
     info->manifest_version = NULL;
     info->main_class = NULL;
     info->jre_version = NULL;
@@ -618,15 +618,17 @@
     zentry  entry;
     void    *data = NULL;
 
-    fd = open(jarfile, O_RDONLY
+    if ((fd = open(jarfile, O_RDONLY
 #ifdef O_LARGEFILE
         | O_LARGEFILE /* large file mode */
 #endif
 #ifdef O_BINARY
         | O_BINARY /* use binary mode on windows */
 #endif
-        );
-    if (fd != -1 && find_file(fd, &entry, filename) == 0) {
+        )) == -1) {
+        return NULL;
+    }
+    if (find_file(fd, &entry, filename) == 0) {
         data = inflate_file(fd, &entry, size);
     }
     close(fd);
@@ -671,8 +673,9 @@
 #ifdef O_BINARY
         | O_BINARY /* use binary mode on windows */
 #endif
-        )) == -1)
+        )) == -1) {
         return (-1);
+    }
 
     if (rc = find_file(fd, &entry, manifest_name) != 0) {
         close(fd);
--- a/src/share/classes/com/sun/beans/finder/MethodFinder.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/com/sun/beans/finder/MethodFinder.java	Mon Feb 25 08:44:00 2013 +0100
@@ -66,11 +66,14 @@
         Signature signature = new Signature(type, name, args);
 
         Method method = CACHE.get(signature);
-        if (method != null) {
+        boolean cached = method != null;
+        if (cached && isPackageAccessible(method.getDeclaringClass())) {
             return method;
         }
         method = findAccessibleMethod(new MethodFinder(name, args).find(type.getMethods()));
-        CACHE.put(signature, method);
+        if (!cached) {
+            CACHE.put(signature, method);
+        }
         return method;
     }
 
--- a/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java	Mon Feb 25 08:44:00 2013 +0100
@@ -41,6 +41,8 @@
 import javax.crypto.SecretKey;
 import javax.crypto.spec.*;
 
+import sun.security.util.KeyUtil;
+
 /**
  * This class implements the Diffie-Hellman key agreement protocol between
  * any number of parties.
@@ -200,6 +202,9 @@
             throw new InvalidKeyException("Incompatible parameters");
         }
 
+        // validate the Diffie-Hellman public key
+        KeyUtil.validate(dhPubKey);
+
         // store the y value
         this.y = dhPubKey.getY();
 
--- a/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1000,7 +1000,6 @@
 
         /** Write a constant pool reference. */
         public void putRef(Entry e) {
-            assert(index != null);
             addValue(encodeRefOrNull(e, index));
         }
         public void putRef(Entry e, Index index) {
@@ -1052,6 +1051,8 @@
 
 
     int encodeRef(Entry e, Index ix) {
+        if (ix == null)
+            throw new RuntimeException("null index for " + e.stringValue());
         int coding = ix.indexOf(e);
         if (verbose > 2)
             Utils.log.fine("putRef "+coding+" => "+e);
--- a/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1405,6 +1405,8 @@
 
         /** Index of all CP entries of a given tag and class. */
         public Index getMemberIndex(byte tag, ClassEntry classRef) {
+            if (classRef == null)
+                throw new RuntimeException("missing class reference for " + tagName(tag));
             if (indexByTagAndClass == null)
                 indexByTagAndClass = new Index[CONSTANT_Limit][];
             Index allClasses =  getIndexByTag(CONSTANT_Class);
--- a/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java	Mon Feb 25 08:44:00 2013 +0100
@@ -109,6 +109,10 @@
         return (p200 == null)? null: p200._nunp;
     }
 
+    private synchronized long getUnpackerPtr() {
+        return unpackerPtr;
+    }
+
     // Callback from the unpacker engine to get more data.
     private long readInputFn(ByteBuffer pbuf, long minlen) throws IOException {
         if (in == null)  return 0;  // nothing is readable
--- a/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java	Mon Feb 25 08:44:00 2013 +0100
@@ -83,7 +83,7 @@
      * @param out an OutputStream
      * @exception IOException if an error is encountered.
      */
-    public void pack(JarFile in, OutputStream out) throws IOException {
+    public synchronized void pack(JarFile in, OutputStream out) throws IOException {
         assert(Utils.currentInstance.get() == null);
         TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE))
                       ? null
@@ -118,7 +118,7 @@
      * @param out an OutputStream
      * @exception IOException if an error is encountered.
      */
-    public void pack(JarInputStream in, OutputStream out) throws IOException {
+    public synchronized void pack(JarInputStream in, OutputStream out) throws IOException {
         assert(Utils.currentInstance.get() == null);
         TimeZone tz = (props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
             TimeZone.getDefault();
--- a/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -106,7 +106,7 @@
      * @param out a JarOutputStream.
      * @exception IOException if an error is encountered.
      */
-    public void unpack(InputStream in, JarOutputStream out) throws IOException {
+    public synchronized void unpack(InputStream in, JarOutputStream out) throws IOException {
         if (in == null) {
             throw new NullPointerException("null input");
         }
@@ -151,7 +151,7 @@
      * @param out a JarOutputStream.
      * @exception IOException if an error is encountered.
      */
-    public void unpack(File in, JarOutputStream out) throws IOException {
+    public synchronized void unpack(File in, JarOutputStream out) throws IOException {
         if (in == null) {
             throw new NullPointerException("null input");
         }
--- a/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java	Mon Feb 25 08:44:00 2013 +0100
@@ -36,6 +36,7 @@
 
 import javax.management.ObjectName;
 import javax.management.loading.PrivateClassLoader;
+import sun.reflect.misc.ReflectUtil;
 
 /**
  * This class keeps the list of Class Loaders registered in the MBean Server.
@@ -192,6 +193,7 @@
                                final ClassLoader without,
                                final ClassLoader stop)
             throws ClassNotFoundException {
+        ReflectUtil.checkPackageAccess(className);
         final int size = list.length;
         for(int i=0; i<size; i++) {
             try {
--- a/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Mon Feb 25 08:44:00 2013 +0100
@@ -54,6 +54,8 @@
 import java.lang.reflect.InvocationTargetException;
 import javax.management.AttributeNotFoundException;
 import javax.management.openmbean.CompositeData;
+import sun.reflect.misc.MethodUtil;
+import sun.reflect.misc.ReflectUtil;
 
 /**
  * This class contains the methods for performing all the tests needed to verify
@@ -526,8 +528,10 @@
                     // to locate method
                     readMethod = SimpleIntrospector.getReadMethod(clazz, element);
                 }
-                if (readMethod != null)
-                    return readMethod.invoke(complex);
+                if (readMethod != null) {
+                    ReflectUtil.checkPackageAccess(readMethod.getDeclaringClass());
+                    return MethodUtil.invoke(readMethod, complex, new Class[0]);
+                }
 
                 throw new AttributeNotFoundException(
                     "Could not find the getter method for the property " +
--- a/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java	Mon Feb 25 08:44:00 2013 +0100
@@ -51,6 +51,7 @@
 import javax.management.MBeanRegistrationException;
 import javax.management.MBeanServer;
 import javax.management.MBeanServerDelegate;
+import javax.management.MBeanServerPermission;
 import javax.management.NotCompliantMBeanException;
 import javax.management.NotificationFilter;
 import javax.management.NotificationListener;
@@ -1409,6 +1410,8 @@
         // Default is true.
         final boolean fairLock = DEFAULT_FAIR_LOCK_POLICY;
 
+        checkNewMBeanServerPermission();
+
         // This constructor happens to disregard the value of the interceptors
         // flag - that is, it always uses the default value - false.
         // This is admitedly a bug, but we chose not to fix it for now
@@ -1494,4 +1497,11 @@
         }
     }
 
+    private static void checkNewMBeanServerPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            Permission perm = new MBeanServerPermission("newMBeanServer");
+            sm.checkPermission(perm);
+        }
+    }
 }
--- a/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java	Mon Feb 25 08:44:00 2013 +0100
@@ -32,11 +32,13 @@
 import java.io.ObjectInputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
+import java.security.Permission;
 import java.util.Map;
 import java.util.logging.Level;
 
 import javax.management.InstanceNotFoundException;
 import javax.management.MBeanException;
+import javax.management.MBeanPermission;
 import javax.management.NotCompliantMBeanException;
 import javax.management.ObjectName;
 import javax.management.OperationsException;
@@ -44,7 +46,7 @@
 import javax.management.RuntimeErrorException;
 import javax.management.RuntimeMBeanException;
 import javax.management.RuntimeOperationsException;
-
+import sun.reflect.misc.ConstructorUtil;
 import sun.reflect.misc.ReflectUtil;
 
 /**
@@ -56,7 +58,6 @@
  * @since 1.5
  */
 public class MBeanInstantiator {
-
     private final ModifiableClassLoaderRepository clr;
     //    private MetaData meta = null;
 
@@ -88,6 +89,7 @@
                              "Exception occurred during object instantiation");
         }
 
+        ReflectUtil.checkPackageAccess(className);
         try {
             if (clr == null) throw new ClassNotFoundException(className);
             theClass = clr.loadClass(className);
@@ -162,6 +164,7 @@
                     continue;
                 }
 
+                ReflectUtil.checkPackageAccess(signature[i]);
                 // Ok we do not have a primitive type ! We need to build
                 // the signature of the method
                 //
@@ -205,6 +208,9 @@
      */
     public Object instantiate(Class<?> theClass)
         throws ReflectionException, MBeanException {
+
+        checkMBeanPermission(theClass, null, null, "instantiate");
+
         Object moi;
 
 
@@ -260,6 +266,9 @@
     public Object instantiate(Class<?> theClass, Object params[],
                               String signature[], ClassLoader loader)
         throws ReflectionException, MBeanException {
+
+        checkMBeanPermission(theClass, null, null, "instantiate");
+
         // Instantiate the new object
 
         // ------------------------------
@@ -407,6 +416,8 @@
             throw new  RuntimeOperationsException(new
              IllegalArgumentException(), "Null className passed in parameter");
         }
+
+        ReflectUtil.checkPackageAccess(className);
         Class<?> theClass;
         if (loaderName == null) {
             // Load the class using the agent class loader
@@ -619,13 +630,13 @@
      **/
     static Class<?> loadClass(String className, ClassLoader loader)
         throws ReflectionException {
-
         Class<?> theClass;
         if (className == null) {
             throw new RuntimeOperationsException(new
                 IllegalArgumentException("The class name cannot be null"),
                               "Exception occurred during object instantiation");
         }
+        ReflectUtil.checkPackageAccess(className);
         try {
             if (loader == null)
                 loader = MBeanInstantiator.class.getClassLoader();
@@ -676,6 +687,7 @@
                 // We need to load the class through the class
                 // loader of the target object.
                 //
+                ReflectUtil.checkPackageAccess(signature[i]);
                 tab[i] = Class.forName(signature[i], false, aLoader);
             }
         } catch (ClassNotFoundException e) {
@@ -701,7 +713,7 @@
 
     private Constructor<?> findConstructor(Class<?> c, Class<?>[] params) {
         try {
-            return c.getConstructor(params);
+            return ConstructorUtil.getConstructor(c, params);
         } catch (Exception e) {
             return null;
         }
@@ -715,4 +727,18 @@
                                           char.class, boolean.class})
             primitiveClasses.put(c.getName(), c);
     }
+
+    private static void checkMBeanPermission(Class<?> clazz,
+                                             String member,
+                                             ObjectName objectName,
+                                             String actions) {
+        SecurityManager sm = System.getSecurityManager();
+        if (clazz != null && sm != null) {
+            Permission perm = new MBeanPermission(clazz.getName(),
+                                                  member,
+                                                  objectName,
+                                                  actions);
+            sm.checkPermission(perm);
+        }
+    }
 }
--- a/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java	Mon Feb 25 08:44:00 2013 +0100
@@ -38,6 +38,7 @@
 import javax.management.ObjectName;
 import javax.management.ReflectionException;
 import com.sun.jmx.mbeanserver.MXBeanMappingFactory;
+import sun.reflect.misc.ReflectUtil;
 
 /**
  * Base class for MBeans.  There is one instance of this class for
@@ -131,6 +132,7 @@
                 " is not an instance of " + mbeanInterfaceType.getName();
             throw new NotCompliantMBeanException(msg);
         }
+        ReflectUtil.checkPackageAccess(mbeanInterfaceType);
         this.resource = resource;
         MBeanIntrospector<M> introspector = getMBeanIntrospector();
         this.perInterface = introspector.getPerInterface(mbeanInterfaceType);
--- a/src/share/classes/java/awt/Dialog.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/awt/Dialog.java	Mon Feb 25 08:44:00 2013 +0100
@@ -39,6 +39,7 @@
 import sun.awt.util.IdentityArrayList;
 import sun.awt.util.IdentityLinkedList;
 import sun.security.util.SecurityConstants;
+import java.security.AccessControlException;
 
 /**
  * A Dialog is a top-level window with a title and a border
@@ -128,6 +129,8 @@
      */
     boolean undecorated = false;
 
+    private transient boolean initialized = false;
+
     /**
      * Modal dialogs block all input to some top-level windows.
      * Whether a particular window is blocked depends on dialog's type
@@ -671,6 +674,7 @@
         this.title = title;
         setModalityType(modalityType);
         SunToolkit.checkAndSetPolicy(this);
+        initialized = true;
     }
 
     /**
@@ -722,6 +726,7 @@
         this.title = title;
         setModalityType(modalityType);
         SunToolkit.checkAndSetPolicy(this);
+        initialized = true;
     }
 
     /**
@@ -851,12 +856,9 @@
         if (modalityType == type) {
             return;
         }
-        if (type == ModalityType.TOOLKIT_MODAL) {
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null) {
-                sm.checkPermission(SecurityConstants.AWT.TOOLKIT_MODALITY_PERMISSION);
-            }
-        }
+
+        checkModalityPermission(type);
+
         modalityType = type;
         modal = (modalityType != ModalityType.MODELESS);
     }
@@ -1025,6 +1027,11 @@
      */
     @Deprecated
     public void show() {
+        if (!initialized) {
+            throw new IllegalStateException("The dialog component " +
+                "has not been initialized properly");
+        }
+
         beforeFirstShow = false;
         if (!isModal()) {
             conditionalShow(null, null);
@@ -1600,18 +1607,51 @@
         }
     }
 
+    private void checkModalityPermission(ModalityType mt) {
+        if (mt == ModalityType.TOOLKIT_MODAL) {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                sm.checkPermission(
+                    SecurityConstants.AWT.TOOLKIT_MODALITY_PERMISSION
+                );
+            }
+        }
+    }
+
     private void readObject(ObjectInputStream s)
         throws ClassNotFoundException, IOException, HeadlessException
     {
         GraphicsEnvironment.checkHeadless();
-        s.defaultReadObject();
+
+        java.io.ObjectInputStream.GetField fields =
+            s.readFields();
+
+        ModalityType localModalityType = (ModalityType)fields.get("modalityType", null);
+
+        try {
+            checkModalityPermission(localModalityType);
+        } catch (AccessControlException ace) {
+            localModalityType = DEFAULT_MODALITY_TYPE;
+        }
 
         // in 1.5 or earlier modalityType was absent, so use "modal" instead
-        if (modalityType == null) {
+        if (localModalityType == null) {
+            this.modal = fields.get("modal", false);
             setModal(modal);
+        } else {
+            this.modalityType = localModalityType;
         }
 
+        this.resizable = fields.get("resizable", true);
+        this.undecorated = fields.get("undecorated", false);
+        this.title = (String)fields.get("title", "");
+
         blockedWindows = new IdentityArrayList<>();
+
+        SunToolkit.checkAndSetPolicy(this);
+
+        initialized = true;
+
     }
 
     /*
--- a/src/share/classes/java/awt/EventQueue.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/awt/EventQueue.java	Mon Feb 25 08:44:00 2013 +0100
@@ -194,7 +194,8 @@
                 }
                 public void removeSourceEvents(EventQueue eventQueue,
                                                Object source,
-                                               boolean removeAllEvents) {
+                                               boolean removeAllEvents)
+                {
                     eventQueue.removeSourceEvents(source, removeAllEvents);
                 }
                 public boolean noEvents(EventQueue eventQueue) {
@@ -203,6 +204,11 @@
                 public void wakeup(EventQueue eventQueue, boolean isShutdown) {
                     eventQueue.wakeup(isShutdown);
                 }
+                public void invokeAndWait(Object source, Runnable r)
+                    throws InterruptedException, InvocationTargetException
+                {
+                    EventQueue.invokeAndWait(source, r);
+                }
             });
     }
 
@@ -1245,8 +1251,14 @@
      * @since           1.2
      */
     public static void invokeAndWait(Runnable runnable)
-             throws InterruptedException, InvocationTargetException {
+        throws InterruptedException, InvocationTargetException
+    {
+        invokeAndWait(Toolkit.getDefaultToolkit(), runnable);
+    }
 
+    static void invokeAndWait(Object source, Runnable runnable)
+        throws InterruptedException, InvocationTargetException
+    {
         if (EventQueue.isDispatchThread()) {
             throw new Error("Cannot call invokeAndWait from the event dispatcher thread");
         }
@@ -1255,8 +1267,7 @@
         Object lock = new AWTInvocationLock();
 
         InvocationEvent event =
-            new InvocationEvent(Toolkit.getDefaultToolkit(), runnable, lock,
-                                true);
+            new InvocationEvent(source, runnable, lock, true);
 
         synchronized (lock) {
             Toolkit.getEventQueue().postEvent(event);
--- a/src/share/classes/java/awt/TextComponent.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/awt/TextComponent.java	Mon Feb 25 08:44:00 2013 +0100
@@ -109,12 +109,6 @@
     // the background color of non-editable TextComponents.
     boolean backgroundSetByClientCode = false;
 
-    /**
-     * True if this <code>TextComponent</code> has access
-     * to the System clipboard.
-     */
-    transient private boolean canAccessClipboard;
-
     transient protected TextListener textListener;
 
     /*
@@ -139,7 +133,6 @@
         GraphicsEnvironment.checkHeadless();
         this.text = (text != null) ? text : "";
         setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
-        checkSystemClipboardAccess();
     }
 
     private void enableInputMethodsIfNecessary() {
@@ -734,17 +727,14 @@
     /**
      * Assigns a valid value to the canAccessClipboard instance variable.
      */
-    private void checkSystemClipboardAccess() {
-        canAccessClipboard = true;
+    private boolean canAccessClipboard() {
         SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            try {
-                sm.checkSystemClipboardAccess();
-            }
-            catch (SecurityException e) {
-                canAccessClipboard = false;
-            }
-        }
+        if (sm == null) return true;
+        try {
+            sm.checkSystemClipboardAccess();
+            return true;
+        } catch (SecurityException e) {}
+        return false;
     }
 
     /*
@@ -827,7 +817,6 @@
             }
         }
         enableInputMethodsIfNecessary();
-        checkSystemClipboardAccess();
     }
 
 
--- a/src/share/classes/java/awt/Window.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/awt/Window.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1206,7 +1206,7 @@
         }
         else {
             try {
-                EventQueue.invokeAndWait(action);
+                EventQueue.invokeAndWait(this, action);
             }
             catch (InterruptedException e) {
                 System.err.println("Disposal was interrupted:");
--- a/src/share/classes/java/io/ObjectInputStream.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/io/ObjectInputStream.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1752,6 +1752,12 @@
         ObjectStreamClass desc = readClassDesc(false);
         desc.checkDeserialize();
 
+        Class<?> cl = desc.forClass();
+        if (cl == String.class || cl == Class.class
+                || cl == ObjectStreamClass.class) {
+            throw new InvalidClassException("invalid class descriptor");
+        }
+
         Object obj;
         try {
             obj = desc.isInstantiable() ? desc.newInstance() : null;
--- a/src/share/classes/java/lang/Class.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/lang/Class.java	Mon Feb 25 08:44:00 2013 +0100
@@ -63,7 +63,9 @@
 import sun.reflect.generics.scope.ClassScope;
 import sun.security.util.SecurityConstants;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Proxy;
 import sun.reflect.annotation.*;
+import sun.reflect.misc.ReflectUtil;
 
 /**
  * Instances of the class {@code Class} represent classes and
@@ -250,11 +252,11 @@
                                    ClassLoader loader)
         throws ClassNotFoundException
     {
-        if (loader == null) {
+        if (sun.misc.VM.isSystemDomainLoader(loader)) {
             SecurityManager sm = System.getSecurityManager();
             if (sm != null) {
                 ClassLoader ccl = ClassLoader.getCallerClassLoader();
-                if (ccl != null) {
+                if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
                     sm.checkPermission(
                         SecurityConstants.GET_CLASSLOADER_PERMISSION);
                 }
@@ -319,7 +321,7 @@
         throws InstantiationException, IllegalAccessException
     {
         if (System.getSecurityManager() != null) {
-            checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+            checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
         }
         return newInstance0();
     }
@@ -1299,7 +1301,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
 
         // Privileged so this implementation can look at DECLARED classes,
         // something the caller might not have privilege to do.  The code here
@@ -1374,7 +1376,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
         return copyFields(privateGetPublicFields(null));
     }
 
@@ -1425,7 +1427,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
         return copyMethods(privateGetPublicMethods());
     }
 
@@ -1474,7 +1476,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
         return copyConstructors(privateGetDeclaredConstructors(true));
     }
 
@@ -1533,7 +1535,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
         Field field = getField0(name);
         if (field == null) {
             throw new NoSuchFieldException(name);
@@ -1618,7 +1620,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
         Method method = getMethod0(name, parameterTypes);
         if (method == null) {
             throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -1672,7 +1674,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
         return getConstructor0(parameterTypes, Member.PUBLIC);
     }
 
@@ -1714,7 +1716,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), false);
         return getDeclaredClasses0();
     }
 
@@ -1758,7 +1760,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
         return copyFields(privateGetDeclaredFields(false));
     }
 
@@ -1806,7 +1808,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
         return copyMethods(privateGetDeclaredMethods(false));
     }
 
@@ -1851,7 +1853,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
         return copyConstructors(privateGetDeclaredConstructors(false));
     }
 
@@ -1895,7 +1897,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
         Field field = searchFields(privateGetDeclaredFields(false), name);
         if (field == null) {
             throw new NoSuchFieldException(name);
@@ -1950,7 +1952,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
         Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
         if (method == null) {
             throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
@@ -2000,7 +2002,7 @@
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
         return getConstructor0(parameterTypes, Member.DECLARED);
     }
 
@@ -2170,18 +2172,26 @@
      * <p> Default policy: allow all clients access with normal Java access
      * control.
      */
-    private void checkMemberAccess(int which, ClassLoader ccl) {
+    private void checkMemberAccess(int which, ClassLoader ccl, boolean checkProxyInterfaces) {
         SecurityManager s = System.getSecurityManager();
         if (s != null) {
             s.checkMemberAccess(this, which);
             ClassLoader cl = getClassLoader0();
-            if (sun.reflect.misc.ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
+            if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
                 String name = this.getName();
                 int i = name.lastIndexOf('.');
                 if (i != -1) {
-                    s.checkPackageAccess(name.substring(0, i));
+                    // skip the package access check on a proxy class in default proxy package
+                    String pkg = name.substring(0, i);
+                    if (!Proxy.isProxyClass(this) || !pkg.equals(ReflectUtil.PROXY_PACKAGE)) {
+                        s.checkPackageAccess(pkg);
+                    }
                 }
             }
+            // check package access on the proxy interfaces
+            if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
+                ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
+            }
         }
     }
 
--- a/src/share/classes/java/lang/invoke/MethodHandleNatives.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/lang/invoke/MethodHandleNatives.java	Mon Feb 25 08:44:00 2013 +0100
@@ -476,6 +476,8 @@
         case "getProxyClass":
         case "newProxyInstance":
             return defc == java.lang.reflect.Proxy.class;
+        case "asInterfaceInstance":
+            return defc == java.lang.invoke.MethodHandleProxies.class;
         case "getBundle":
         case "clearCache":
             return defc == java.util.ResourceBundle.class;
--- a/src/share/classes/java/lang/invoke/MethodHandleProxies.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/lang/invoke/MethodHandleProxies.java	Mon Feb 25 08:44:00 2013 +0100
@@ -26,8 +26,12 @@
 package java.lang.invoke;
 
 import java.lang.reflect.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import sun.invoke.WrapperInstance;
 import java.util.ArrayList;
+import sun.reflect.Reflection;
+import sun.reflect.misc.ReflectUtil;
 
 /**
  * This class consists exclusively of static methods that help adapt
@@ -137,6 +141,21 @@
     <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
         if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
             throw new IllegalArgumentException("not a public interface: "+intfc.getName());
+        final MethodHandle mh;
+        if (System.getSecurityManager() != null) {
+            final int CALLER_FRAME = 2; // 0: Reflection, 1: asInterfaceInstance, 2: caller
+            final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
+            final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
+            ReflectUtil.checkProxyPackageAccess(ccl, intfc);
+            mh = ccl != null ? bindCaller(target, caller) : target;
+        } else {
+            mh = target;
+        }
+        ClassLoader proxyLoader = intfc.getClassLoader();
+        if (proxyLoader == null) {
+            ClassLoader cl = Thread.currentThread().getContextClassLoader(); // avoid use of BCP
+            proxyLoader = cl != null ? cl : ClassLoader.getSystemClassLoader();
+        }
         final Method[] methods = getSingleNameMethods(intfc);
         if (methods == null)
             throw new IllegalArgumentException("not a single-method interface: "+intfc.getName());
@@ -144,31 +163,58 @@
         for (int i = 0; i < methods.length; i++) {
             Method sm = methods[i];
             MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes());
-            MethodHandle checkTarget = target.asType(smMT);  // make throw WMT
+            MethodHandle checkTarget = mh.asType(smMT);  // make throw WMT
             checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
             vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount());
         }
-        return intfc.cast(Proxy.newProxyInstance(
-                intfc.getClassLoader(),
-                new Class<?>[]{ intfc, WrapperInstance.class },
-                new InvocationHandler() {
-                    private Object getArg(String name) {
-                        if ((Object)name == "getWrapperInstanceTarget")  return target;
-                        if ((Object)name == "getWrapperInstanceType")    return intfc;
-                        throw new AssertionError();
+        final InvocationHandler ih = new InvocationHandler() {
+                private Object getArg(String name) {
+                    if ((Object)name == "getWrapperInstanceTarget")  return target;
+                    if ((Object)name == "getWrapperInstanceType")    return intfc;
+                    throw new AssertionError();
+                }
+                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+                    for (int i = 0; i < methods.length; i++) {
+                        if (method.equals(methods[i]))
+                            return vaTargets[i].invokeExact(args);
                     }
-                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-                        for (int i = 0; i < methods.length; i++) {
-                            if (method.equals(methods[i]))
-                                return vaTargets[i].invokeExact(args);
-                        }
-                        if (method.getDeclaringClass() == WrapperInstance.class)
-                            return getArg(method.getName());
-                        if (isObjectMethod(method))
-                            return callObjectMethod(proxy, method, args);
-                        throw new InternalError("bad proxy method: "+method);
-                    }
-                }));
+                    if (method.getDeclaringClass() == WrapperInstance.class)
+                        return getArg(method.getName());
+                    if (isObjectMethod(method))
+                        return callObjectMethod(proxy, method, args);
+                    throw new InternalError("bad proxy method: "+method);
+                }
+            };
+
+        final Object proxy;
+        if (System.getSecurityManager() != null) {
+            // sun.invoke.WrapperInstance is a restricted interface not accessible
+            // by any non-null class loader.
+            final ClassLoader loader = proxyLoader;
+            proxy = AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                public Object run() {
+                    return Proxy.newProxyInstance(
+                            loader,
+                            new Class<?>[]{ intfc, WrapperInstance.class },
+                            ih);
+                }
+            });
+        } else {
+            proxy = Proxy.newProxyInstance(proxyLoader,
+                                           new Class<?>[]{ intfc, WrapperInstance.class },
+                                           ih);
+        }
+        return intfc.cast(proxy);
+    }
+
+    private static MethodHandle bindCaller(MethodHandle target, Class<?> hostClass) {
+        MethodHandle cbmh = MethodHandleImpl.bindCaller(target, hostClass);
+        if (target.isVarargsCollector()) {
+            MethodType type = cbmh.type();
+            int arity = type.parameterCount();
+            return cbmh.asVarargsCollector(type.parameterType(arity-1));
+        }
+        return cbmh;
     }
 
     /**
--- a/src/share/classes/java/lang/management/ManagementFactory.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/lang/management/ManagementFactory.java	Mon Feb 25 08:44:00 2013 +0100
@@ -802,20 +802,20 @@
      */
     private static void addMXBean(final MBeanServer mbs, final PlatformManagedObject pmo) {
         // Make DynamicMBean out of MXBean by wrapping it with a StandardMBean
-        final DynamicMBean dmbean;
-        if (pmo instanceof DynamicMBean) {
-            dmbean = DynamicMBean.class.cast(pmo);
-        } else if (pmo instanceof NotificationEmitter) {
-            dmbean = new StandardEmitterMBean(pmo, null, true, (NotificationEmitter) pmo);
-        } else {
-            dmbean = new StandardMBean(pmo, null, true);
-        }
-
         try {
             AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
                 public Void run() throws InstanceAlreadyExistsException,
                                          MBeanRegistrationException,
                                          NotCompliantMBeanException {
+                    final DynamicMBean dmbean;
+                    if (pmo instanceof DynamicMBean) {
+                        dmbean = DynamicMBean.class.cast(pmo);
+                    } else if (pmo instanceof NotificationEmitter) {
+                        dmbean = new StandardEmitterMBean(pmo, null, true, (NotificationEmitter) pmo);
+                    } else {
+                        dmbean = new StandardMBean(pmo, null, true);
+                    }
+
                     mbs.registerMBean(dmbean, pmo.getObjectName());
                     return null;
                 }
--- a/src/share/classes/java/lang/reflect/Proxy.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/lang/reflect/Proxy.java	Mon Feb 25 08:44:00 2013 +0100
@@ -27,6 +27,9 @@
 
 import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PrivilegedAction;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
@@ -36,6 +39,9 @@
 import java.util.List;
 import java.util.WeakHashMap;
 import sun.misc.ProxyGenerator;
+import sun.reflect.Reflection;
+import sun.reflect.misc.ReflectUtil;
+import sun.security.util.SecurityConstants;
 
 /**
  * {@code Proxy} provides static methods for creating dynamic proxy
@@ -265,9 +271,69 @@
      * @param   h the invocation handler for this proxy instance
      */
     protected Proxy(InvocationHandler h) {
+        doNewInstanceCheck();
         this.h = h;
     }
 
+    private static class ProxyAccessHelper {
+        // The permission is implementation specific.
+        static final Permission PROXY_PERMISSION =
+            new ReflectPermission("proxyConstructorNewInstance");
+        // These system properties are defined to provide a short-term
+        // workaround if customers need to disable the new security checks.
+        static final boolean allowNewInstance;
+        static final boolean allowNullLoader;
+        static {
+            allowNewInstance = getBooleanProperty("sun.reflect.proxy.allowsNewInstance");
+            allowNullLoader = getBooleanProperty("sun.reflect.proxy.allowsNullLoader");
+        }
+
+        private static boolean getBooleanProperty(final String key) {
+            String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty(key);
+                }
+            });
+            return Boolean.valueOf(s);
+        }
+
+        static boolean needsNewInstanceCheck(Class<?> proxyClass) {
+            if (!Proxy.isProxyClass(proxyClass) || allowNewInstance) {
+                return false;
+            }
+
+            if (proxyClass.getName().startsWith(ReflectUtil.PROXY_PACKAGE + ".")) {
+                // all proxy interfaces are public
+                return false;
+            }
+            for (Class<?> intf : proxyClass.getInterfaces()) {
+                if (!Modifier.isPublic(intf.getModifiers())) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    /*
+     * Access check on a proxy class that implements any non-public interface.
+     *
+     * @throws  SecurityException if a security manager exists, and
+     *          the caller does not have the permission.
+     */
+    private void doNewInstanceCheck() {
+        SecurityManager sm = System.getSecurityManager();
+        Class<?> proxyClass = this.getClass();
+        if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(proxyClass)) {
+            try {
+                sm.checkPermission(ProxyAccessHelper.PROXY_PERMISSION);
+            } catch (SecurityException e) {
+                throw new SecurityException("Not allowed to construct a Proxy "
+                        + "instance that implements a non-public interface", e);
+            }
+        }
+    }
+
     /**
      * Returns the {@code java.lang.Class} object for a proxy class
      * given a class loader and an array of interfaces.  The proxy class
@@ -346,6 +412,51 @@
                                          Class<?>... interfaces)
         throws IllegalArgumentException
     {
+        return getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
+    }
+
+    private static void checkProxyLoader(ClassLoader ccl,
+                                         ClassLoader loader)
+    {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            if (loader == null && ccl != null) {
+                if (!ProxyAccessHelper.allowNullLoader) {
+                    sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
+                }
+            }
+        }
+    }
+
+    /*
+     * Generate a proxy class (caller-sensitive).
+     *
+     * To define a proxy class, it performs the access checks as in
+     * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
+     * 1. "getClassLoader" permission check if loader == null
+     * 2. checkPackageAccess on the interfaces it implements
+     *
+     * To get a constructor and new instance of a proxy class, it performs
+     * the package access check on the interfaces it implements
+     * as in Class.getConstructor.
+     *
+     * If an interface is non-public, the proxy class must be defined by
+     * the defining loader of the interface.  If the caller's class loader
+     * is not the same as the defining loader of the interface, the VM
+     * will throw IllegalAccessError when the generated proxy class is
+     * being defined via the defineClass0 method.
+     */
+    private static Class<?> getProxyClass0(ClassLoader loader,
+                                           Class<?>... interfaces) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            final int CALLER_FRAME = 3; // 0: Reflection, 1: getProxyClass0 2: Proxy 3: caller
+            final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
+            final ClassLoader ccl = caller.getClassLoader();
+            checkProxyLoader(ccl, loader);
+            ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
+        }
+
         if (interfaces.length > 65535) {
             throw new IllegalArgumentException("interface limit exceeded");
         }
@@ -497,8 +608,9 @@
                 }
             }
 
-            if (proxyPkg == null) {     // if no non-public proxy interfaces,
-                proxyPkg = "";          // use the unnamed package
+            if (proxyPkg == null) {
+                // if no non-public proxy interfaces, use com.sun.proxy package
+                proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
             }
 
             {
@@ -598,22 +710,46 @@
         /*
          * Look up or generate the designated proxy class.
          */
-        Class<?> cl = getProxyClass(loader, interfaces);
+        Class<?> cl = getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
 
         /*
          * Invoke its constructor with the designated invocation handler.
          */
         try {
-            Constructor<?> cons = cl.getConstructor(constructorParams);
-            return cons.newInstance(new Object[] { h });
-        } catch (NoSuchMethodException |
-                 IllegalAccessException |
-                 InstantiationException |
-                 InvocationTargetException e) {
+            final Constructor<?> cons = cl.getConstructor(constructorParams);
+            final InvocationHandler ih = h;
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
+                // create proxy instance with doPrivilege as the proxy class may
+                // implement non-public interfaces that requires a special permission
+                return AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                    public Object run() {
+                        return newInstance(cons, ih);
+                    }
+                });
+            } else {
+                return newInstance(cons, ih);
+            }
+        } catch (NoSuchMethodException e) {
             throw new InternalError(e.toString(), e);
         }
     }
 
+    private static Object newInstance(Constructor<?> cons, InvocationHandler h) {
+        try {
+            return cons.newInstance(new Object[] {h} );
+        } catch (IllegalAccessException | InstantiationException e) {
+            throw new InternalError(e.toString(), e);
+        } catch (InvocationTargetException e) {
+            Throwable t = e.getCause();
+            if (t instanceof RuntimeException) {
+                throw (RuntimeException) t;
+            } else {
+                throw new InternalError(t.toString(), t);
+            }
+        }
+    }
+
     /**
      * Returns true if and only if the specified class was dynamically
      * generated to be a proxy class using the {@code getProxyClass}
--- a/src/share/classes/java/net/InetSocketAddress.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/net/InetSocketAddress.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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,9 +24,12 @@
  */
 package java.net;
 
-import java.io.ObjectInputStream;
 import java.io.IOException;
 import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.ObjectStreamField;
 
 /**
  *
@@ -46,23 +49,105 @@
  * @see java.net.ServerSocket
  * @since 1.4
  */
-public class InetSocketAddress extends SocketAddress {
-    /* The hostname of the Socket Address
-     * @serial
-     */
-    private String hostname = null;
-    /* The IP address of the Socket Address
-     * @serial
-     */
-    private InetAddress addr = null;
-    /* The port number of the Socket Address
-     * @serial
-     */
-    private int port;
+public class InetSocketAddress
+    extends SocketAddress
+{
+    // Private implementation class pointed to by all public methods.
+    private static class InetSocketAddressHolder {
+        // The hostname of the Socket Address
+        private String hostname;
+        // The IP address of the Socket Address
+        private InetAddress addr;
+        // The port number of the Socket Address
+        private int port;
+
+        private InetSocketAddressHolder(String hostname, InetAddress addr, int port) {
+            this.hostname = hostname;
+            this.addr = addr;
+            this.port = port;
+        }
+
+        private int getPort() {
+            return port;
+        }
+
+        private InetAddress getAddress() {
+            return addr;
+        }
+
+        private String getHostName() {
+            if (hostname != null)
+                return hostname;
+            if (addr != null)
+                return addr.getHostName();
+            return null;
+        }
+
+        private String getHostString() {
+            if (hostname != null)
+                return hostname;
+            if (addr != null) {
+                if (addr.hostName != null)
+                    return addr.hostName;
+                else
+                    return addr.getHostAddress();
+            }
+            return null;
+        }
+
+        private boolean isUnresolved() {
+            return addr == null;
+        }
+
+        @Override
+        public String toString() {
+            if (isUnresolved()) {
+                return hostname + ":" + port;
+            } else {
+                return addr.toString() + ":" + port;
+            }
+        }
+
+        @Override
+        public final boolean equals(Object obj) {
+            if (obj == null || !(obj instanceof InetSocketAddressHolder))
+                return false;
+            InetSocketAddressHolder that = (InetSocketAddressHolder)obj;
+            boolean sameIP;
+            if (addr != null)
+                sameIP = addr.equals(that.addr);
+            else if (hostname != null)
+                sameIP = (that.addr == null) &&
+                    hostname.equalsIgnoreCase(that.hostname);
+            else
+                sameIP = (that.addr == null) && (that.hostname == null);
+            return sameIP && (port == that.port);
+        }
+
+        @Override
+        public final int hashCode() {
+            if (addr != null)
+                return addr.hashCode() + port;
+            if (hostname != null)
+                return hostname.toLowerCase().hashCode() + port;
+            return port;
+        }
+    }
+
+    private final transient InetSocketAddressHolder holder;
 
     private static final long serialVersionUID = 5076001401234631237L;
 
-    private InetSocketAddress() {
+    private static int checkPort(int port) {
+        if (port < 0 || port > 0xFFFF)
+            throw new IllegalArgumentException("port out of range:" + port);
+        return port;
+    }
+
+    private static String checkHost(String hostname) {
+        if (hostname == null)
+            throw new IllegalArgumentException("hostname can't be null");
+        return hostname;
     }
 
     /**
@@ -97,14 +182,10 @@
      * range of valid port values.
      */
     public InetSocketAddress(InetAddress addr, int port) {
-        if (port < 0 || port > 0xFFFF) {
-            throw new IllegalArgumentException("port out of range:" + port);
-        }
-        this.port = port;
-        if (addr == null)
-            this.addr = InetAddress.anyLocalAddress();
-        else
-            this.addr = addr;
+        holder = new InetSocketAddressHolder(
+                        null,
+                        addr == null ? InetAddress.anyLocalAddress() : addr,
+                        checkPort(port));
     }
 
     /**
@@ -132,19 +213,20 @@
      * @see     #isUnresolved()
      */
     public InetSocketAddress(String hostname, int port) {
-        if (port < 0 || port > 0xFFFF) {
-            throw new IllegalArgumentException("port out of range:" + port);
-        }
-        if (hostname == null) {
-            throw new IllegalArgumentException("hostname can't be null");
-        }
+        checkHost(hostname);
+        InetAddress addr = null;
+        String host = null;
         try {
             addr = InetAddress.getByName(hostname);
         } catch(UnknownHostException e) {
-            this.hostname = hostname;
-            addr = null;
+            host = hostname;
         }
-        this.port = port;
+        holder = new InetSocketAddressHolder(host, addr, checkPort(port));
+    }
+
+    // private constructor for creating unresolved instances
+    private InetSocketAddress(int port, String hostname) {
+        holder = new InetSocketAddressHolder(hostname, null, port);
     }
 
     /**
@@ -169,31 +251,67 @@
      * @since 1.5
      */
     public static InetSocketAddress createUnresolved(String host, int port) {
-        if (port < 0 || port > 0xFFFF) {
-            throw new IllegalArgumentException("port out of range:" + port);
-        }
-        if (host == null) {
-            throw new IllegalArgumentException("hostname can't be null");
-        }
-        InetSocketAddress s = new InetSocketAddress();
-        s.port = port;
-        s.hostname = host;
-        s.addr = null;
-        return s;
+        return new InetSocketAddress(checkPort(port), checkHost(host));
     }
 
-    private void readObject(ObjectInputStream s)
-        throws IOException, ClassNotFoundException {
-        s.defaultReadObject();
+    /**
+     * @serialField hostname String
+     * @serialField addr InetAddress
+     * @serialField port int
+     */
+    private static final ObjectStreamField[] serialPersistentFields = {
+         new ObjectStreamField("hostname", String.class),
+         new ObjectStreamField("addr", InetAddress.class),
+         new ObjectStreamField("port", int.class)};
+
+    private void writeObject(ObjectOutputStream out)
+        throws IOException
+    {
+        // Don't call defaultWriteObject()
+         ObjectOutputStream.PutField pfields = out.putFields();
+         pfields.put("hostname", holder.hostname);
+         pfields.put("addr", holder.addr);
+         pfields.put("port", holder.port);
+         out.writeFields();
+     }
+
+    private void readObject(ObjectInputStream in)
+        throws IOException, ClassNotFoundException
+    {
+        // Don't call defaultReadObject()
+        ObjectInputStream.GetField oisFields = in.readFields();
+        final String oisHostname = (String)oisFields.get("hostname", null);
+        final InetAddress oisAddr = (InetAddress)oisFields.get("addr", null);
+        final int oisPort = oisFields.get("port", -1);
 
         // Check that our invariants are satisfied
-        if (port < 0 || port > 0xFFFF) {
-            throw new InvalidObjectException("port out of range:" + port);
-        }
-
-        if (hostname == null && addr == null) {
+        checkPort(oisPort);
+        if (oisHostname == null && oisAddr == null)
             throw new InvalidObjectException("hostname and addr " +
                                              "can't both be null");
+
+        InetSocketAddressHolder h = new InetSocketAddressHolder(oisHostname,
+                                                                oisAddr,
+                                                                oisPort);
+        UNSAFE.putObject(this, FIELDS_OFFSET, h);
+    }
+
+    private void readObjectNoData()
+        throws ObjectStreamException
+    {
+        throw new InvalidObjectException("Stream data required");
+    }
+
+    private static final long FIELDS_OFFSET;
+    private static final sun.misc.Unsafe UNSAFE;
+    static {
+        try {
+            sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+            FIELDS_OFFSET = unsafe.objectFieldOffset(
+                    InetSocketAddress.class.getDeclaredField("holder"));
+            UNSAFE = unsafe;
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
         }
     }
 
@@ -203,7 +321,7 @@
      * @return the port number.
      */
     public final int getPort() {
-        return port;
+        return holder.getPort();
     }
 
     /**
@@ -213,7 +331,7 @@
      * @return the InetAdress or <code>null</code> if it is unresolved.
      */
     public final InetAddress getAddress() {
-        return addr;
+        return holder.getAddress();
     }
 
     /**
@@ -224,31 +342,19 @@
      * @return  the hostname part of the address.
      */
     public final String getHostName() {
-        if (hostname != null)
-            return hostname;
-        if (addr != null)
-            return addr.getHostName();
-        return null;
+        return holder.getHostName();
     }
 
     /**
      * Returns the hostname, or the String form of the address if it
      * doesn't have a hostname (it was created using a literal).
-     * This has the benefit of <b>not</b> attemptimg a reverse lookup.
+     * This has the benefit of <b>not</b> attempting a reverse lookup.
      *
      * @return the hostname, or String representation of the address.
      * @since 1.7
      */
     public final String getHostString() {
-        if (hostname != null)
-            return hostname;
-        if (addr != null) {
-            if (addr.hostName != null)
-                return addr.hostName;
-            else
-                return addr.getHostAddress();
-        }
-        return null;
+        return holder.getHostString();
     }
 
     /**
@@ -258,7 +364,7 @@
      *          an <code>InetAddress</code>.
      */
     public final boolean isUnresolved() {
-        return addr == null;
+        return holder.isUnresolved();
     }
 
     /**
@@ -269,12 +375,9 @@
      *
      * @return  a string representation of this object.
      */
+    @Override
     public String toString() {
-        if (isUnresolved()) {
-            return hostname + ":" + port;
-        } else {
-            return addr.toString() + ":" + port;
-        }
+        return holder.toString();
     }
 
     /**
@@ -297,19 +400,11 @@
      *          <code>false</code> otherwise.
      * @see java.net.InetAddress#equals(java.lang.Object)
      */
+    @Override
     public final boolean equals(Object obj) {
         if (obj == null || !(obj instanceof InetSocketAddress))
             return false;
-        InetSocketAddress sockAddr = (InetSocketAddress) obj;
-        boolean sameIP = false;
-        if (this.addr != null)
-            sameIP = this.addr.equals(sockAddr.addr);
-        else if (this.hostname != null)
-            sameIP = (sockAddr.addr == null) &&
-                this.hostname.equalsIgnoreCase(sockAddr.hostname);
-        else
-            sameIP = (sockAddr.addr == null) && (sockAddr.hostname == null);
-        return sameIP && (this.port == sockAddr.port);
+        return holder.equals(((InetSocketAddress) obj).holder);
     }
 
     /**
@@ -317,11 +412,8 @@
      *
      * @return  a hash code value for this socket address.
      */
+    @Override
     public final int hashCode() {
-        if (addr != null)
-            return addr.hashCode() + port;
-        if (hostname != null)
-            return hostname.toLowerCase().hashCode() + port;
-        return port;
+        return holder.hashCode();
     }
 }
--- a/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java	Mon Feb 25 08:44:00 2013 +0100
@@ -34,8 +34,10 @@
  */
 
 package java.util.concurrent;
-import java.util.concurrent.locks.*;
-import java.util.concurrent.atomic.*;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.*;
 
 /**
@@ -491,10 +493,15 @@
      * policy limiting the number of threads.  Even though it is not
      * treated as an error, failure to create threads may result in
      * new tasks being rejected or existing ones remaining stuck in
-     * the queue. On the other hand, no special precautions exist to
-     * handle OutOfMemoryErrors that might be thrown while trying to
-     * create threads, since there is generally no recourse from
-     * within this class.
+     * the queue.
+     *
+     * We go further and preserve pool invariants even in the face of
+     * errors such as OutOfMemoryError, that might be thrown while
+     * trying to create threads.  Such errors are rather common due to
+     * the need to allocate a native stack in Thread#start, and users
+     * will want to perform clean pool shutdown to clean up.  There
+     * will likely be enough memory available for the cleanup code to
+     * complete without encountering yet another OutOfMemoryError.
      */
     private volatile ThreadFactory threadFactory;
 
@@ -568,9 +575,13 @@
      * task execution.  This protects against interrupts that are
      * intended to wake up a worker thread waiting for a task from
      * instead interrupting a task being run.  We implement a simple
-     * non-reentrant mutual exclusion lock rather than use ReentrantLock
-     * because we do not want worker tasks to be able to reacquire the
-     * lock when they invoke pool control methods like setCorePoolSize.
+     * non-reentrant mutual exclusion lock rather than use
+     * ReentrantLock because we do not want worker tasks to be able to
+     * reacquire the lock when they invoke pool control methods like
+     * setCorePoolSize.  Additionally, to suppress interrupts until
+     * the thread actually starts running tasks, we initialize lock
+     * state to a negative value, and clear it upon start (in
+     * runWorker).
      */
     private final class Worker
         extends AbstractQueuedSynchronizer
@@ -594,6 +605,7 @@
          * @param firstTask the first task (null if none)
          */
         Worker(Runnable firstTask) {
+            setState(-1); // inhibit interrupts until runWorker
             this.firstTask = firstTask;
             this.thread = getThreadFactory().newThread(this);
         }
@@ -609,7 +621,7 @@
         // The value 1 represents the locked state.
 
         protected boolean isHeldExclusively() {
-            return getState() == 1;
+            return getState() != 0;
         }
 
         protected boolean tryAcquire(int unused) {
@@ -630,6 +642,16 @@
         public boolean tryLock()  { return tryAcquire(1); }
         public void unlock()      { release(1); }
         public boolean isLocked() { return isHeldExclusively(); }
+
+        void interruptIfStarted() {
+            Thread t;
+            if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
+                try {
+                    t.interrupt();
+                } catch (SecurityException ignore) {
+                }
+            }
+        }
     }
 
     /*
@@ -728,12 +750,8 @@
         final ReentrantLock mainLock = this.mainLock;
         mainLock.lock();
         try {
-            for (Worker w : workers) {
-                try {
-                    w.thread.interrupt();
-                } catch (SecurityException ignore) {
-                }
-            }
+            for (Worker w : workers)
+                w.interruptIfStarted();
         } finally {
             mainLock.unlock();
         }
@@ -790,19 +808,6 @@
 
     private static final boolean ONLY_ONE = true;
 
-    /**
-     * Ensures that unless the pool is stopping, the current thread
-     * does not have its interrupt set. This requires a double-check
-     * of state in case the interrupt was cleared concurrently with a
-     * shutdownNow -- if so, the interrupt is re-enabled.
-     */
-    private void clearInterruptsForTaskRun() {
-        if (runStateLessThan(ctl.get(), STOP) &&
-            Thread.interrupted() &&
-            runStateAtLeast(ctl.get(), STOP))
-            Thread.currentThread().interrupt();
-    }
-
     /*
      * Misc utilities, most of which are also exported to
      * ScheduledThreadPoolExecutor
@@ -862,12 +867,13 @@
      * Checks if a new worker can be added with respect to current
      * pool state and the given bound (either core or maximum). If so,
      * the worker count is adjusted accordingly, and, if possible, a
-     * new worker is created and started running firstTask as its
+     * new worker is created and started, running firstTask as its
      * first task. This method returns false if the pool is stopped or
      * eligible to shut down. It also returns false if the thread
-     * factory fails to create a thread when asked, which requires a
-     * backout of workerCount, and a recheck for termination, in case
-     * the existence of this worker was holding up termination.
+     * factory fails to create a thread when asked.  If the thread
+     * creation fails, either due to the thread factory returning
+     * null, or due to an exception (typically OutOfMemoryError in
+     * Thread#start), we roll back cleanly.
      *
      * @param firstTask the task the new thread should run first (or
      * null if none). Workers are created with an initial first task
@@ -910,46 +916,65 @@
             }
         }
 
-        Worker w = new Worker(firstTask);
-        Thread t = w.thread;
+        boolean workerStarted = false;
+        boolean workerAdded = false;
+        Worker w = null;
+        try {
+            final ReentrantLock mainLock = this.mainLock;
+            w = new Worker(firstTask);
+            final Thread t = w.thread;
+            if (t != null) {
+                mainLock.lock();
+                try {
+                    // Recheck while holding lock.
+                    // Back out on ThreadFactory failure or if
+                    // shut down before lock acquired.
+                    int c = ctl.get();
+                    int rs = runStateOf(c);
 
+                    if (rs < SHUTDOWN ||
+                        (rs == SHUTDOWN && firstTask == null)) {
+                        if (t.isAlive()) // precheck that t is startable
+                            throw new IllegalThreadStateException();
+                        workers.add(w);
+                        int s = workers.size();
+                        if (s > largestPoolSize)
+                            largestPoolSize = s;
+                        workerAdded = true;
+                    }
+                } finally {
+                    mainLock.unlock();
+                }
+                if (workerAdded) {
+                    t.start();
+                    workerStarted = true;
+                }
+            }
+        } finally {
+            if (! workerStarted)
+                addWorkerFailed(w);
+        }
+        return workerStarted;
+    }
+
+    /**
+     * Rolls back the worker thread creation.
+     * - removes worker from workers, if present
+     * - decrements worker count
+     * - rechecks for termination, in case the existence of this
+     *   worker was holding up termination
+     */
+    private void addWorkerFailed(Worker w) {
         final ReentrantLock mainLock = this.mainLock;
         mainLock.lock();
         try {
-            // Recheck while holding lock.
-            // Back out on ThreadFactory failure or if
-            // shut down before lock acquired.
-            int c = ctl.get();
-            int rs = runStateOf(c);
-
-            if (t == null ||
-                (rs >= SHUTDOWN &&
-                 ! (rs == SHUTDOWN &&
-                    firstTask == null))) {
-                decrementWorkerCount();
-                tryTerminate();
-                return false;
-            }
-
-            workers.add(w);
-
-            int s = workers.size();
-            if (s > largestPoolSize)
-                largestPoolSize = s;
+            if (w != null)
+                workers.remove(w);
+            decrementWorkerCount();
+            tryTerminate();
         } finally {
             mainLock.unlock();
         }
-
-        t.start();
-        // It is possible (but unlikely) for a thread to have been
-        // added to workers, but not yet started, during transition to
-        // STOP, which could result in a rare missed interrupt,
-        // because Thread.interrupt is not guaranteed to have any effect
-        // on a non-yet-started Thread (see Thread#interrupt).
-        if (runStateOf(ctl.get()) == STOP && ! t.isInterrupted())
-            t.interrupt();
-
-        return true;
     }
 
     /**
@@ -1096,15 +1121,25 @@
      * @param w the worker
      */
     final void runWorker(Worker w) {
+        Thread wt = Thread.currentThread();
         Runnable task = w.firstTask;
         w.firstTask = null;
+        w.unlock(); // allow interrupts
         boolean completedAbruptly = true;
         try {
             while (task != null || (task = getTask()) != null) {
                 w.lock();
-                clearInterruptsForTaskRun();
+                // If pool is stopping, ensure thread is interrupted;
+                // if not, ensure thread is not interrupted.  This
+                // requires a recheck in second case to deal with
+                // shutdownNow race while clearing interrupt
+                if ((runStateAtLeast(ctl.get(), STOP) ||
+                     (Thread.interrupted() &&
+                      runStateAtLeast(ctl.get(), STOP))) &&
+                    !wt.isInterrupted())
+                    wt.interrupt();
                 try {
-                    beforeExecute(w.thread, task);
+                    beforeExecute(wt, task);
                     Throwable thrown = null;
                     try {
                         task.run();
@@ -2064,3 +2099,4 @@
         }
     }
 }
+
--- a/src/share/classes/java/util/jar/JarFile.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/util/jar/JarFile.java	Mon Feb 25 08:44:00 2013 +0100
@@ -34,6 +34,7 @@
 import java.security.cert.Certificate;
 import java.security.AccessController;
 import java.security.CodeSource;
+import sun.misc.IOUtils;
 import sun.security.action.GetPropertyAction;
 import sun.security.util.ManifestEntryVerifier;
 import sun.misc.SharedSecrets;
@@ -334,6 +335,9 @@
             if (names != null) {
                 for (int i = 0; i < names.length; i++) {
                     JarEntry e = getJarEntry(names[i]);
+                    if (e == null) {
+                        throw new JarException("corrupted jar file");
+                    }
                     if (!e.isDirectory()) {
                         if (mev == null) {
                             mev = new ManifestEntryVerifier
@@ -353,6 +357,10 @@
             // treat the jar file as being unsigned
             jv = null;
             verify = false;
+            if (JarVerifier.debug != null) {
+                JarVerifier.debug.println("jarfile parsing error!");
+                ex.printStackTrace();
+            }
         }
 
         // if after initializing the verifier we have nothing
@@ -380,11 +388,9 @@
      * META-INF files.
      */
     private byte[] getBytes(ZipEntry ze) throws IOException {
-        byte[] b = new byte[(int)ze.getSize()];
-        try (DataInputStream is = new DataInputStream(super.getInputStream(ze))) {
-            is.readFully(b, 0, b.length);
+        try (InputStream is = super.getInputStream(ze)) {
+            return IOUtils.readFully(is, (int)ze.getSize(), true);
         }
-        return b;
     }
 
     /**
@@ -540,11 +546,7 @@
         if (!isKnownNotToHaveSpecialAttributes()) {
             JarEntry manEntry = getManEntry();
             if (manEntry != null) {
-                byte[] b = new byte[(int)manEntry.getSize()];
-                try (DataInputStream dis = new DataInputStream(
-                         super.getInputStream(manEntry))) {
-                    dis.readFully(b, 0, b.length);
-                }
+                byte[] b = getBytes(manEntry);
                 if (match(CLASSPATH_CHARS, b, CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT))
                     hasClassPathAttribute = true;
                 if (match(PROFILE_CHARS, b, PROFILE_LASTOCC, PROFILE_OPTOSFT))
--- a/src/share/classes/java/util/logging/Level.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/util/logging/Level.java	Mon Feb 25 08:44:00 2013 +0100
@@ -24,6 +24,10 @@
  */
 
 package java.util.logging;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.ResourceBundle;
 
 /**
@@ -59,7 +63,6 @@
  */
 
 public class Level implements java.io.Serializable {
-    private static java.util.ArrayList<Level> known = new java.util.ArrayList<>();
     private static String defaultBundle = "sun.util.logging.resources.logging";
 
     /**
@@ -77,6 +80,9 @@
      */
     private final String resourceBundleName;
 
+    // localized level name
+    private String localizedLevelName;
+
     /**
      * OFF is a special level that can be used to turn off logging.
      * This level is initialized to <CODE>Integer.MAX_VALUE</CODE>.
@@ -202,9 +208,8 @@
         this.name = name;
         this.value = value;
         this.resourceBundleName = resourceBundleName;
-        synchronized (Level.class) {
-            known.add(this);
-        }
+        this.localizedLevelName = resourceBundleName == null ? name : null;
+        KnownLevel.add(this);
     }
 
     /**
@@ -236,12 +241,76 @@
      * @return localized name
      */
     public String getLocalizedName() {
+        return getLocalizedLevelName();
+    }
+
+    // package-private getLevelName() is used by the implementation
+    // instead of getName() to avoid calling the subclass's version
+    final String getLevelName() {
+        return this.name;
+    }
+
+    final synchronized String getLocalizedLevelName() {
+        if (localizedLevelName != null) {
+            return localizedLevelName;
+        }
+
         try {
             ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName);
-            return rb.getString(name);
+            localizedLevelName = rb.getString(name);
         } catch (Exception ex) {
-            return name;
+            localizedLevelName = name;
         }
+        return localizedLevelName;
+    }
+
+    // Returns a mirrored Level object that matches the given name as
+    // specified in the Level.parse method.  Returns null if not found.
+    //
+    // It returns the same Level object as the one returned by Level.parse
+    // method if the given name is a non-localized name or integer.
+    //
+    // If the name is a localized name, findLevel and parse method may
+    // return a different level value if there is a custom Level subclass
+    // that overrides Level.getLocalizedName() to return a different string
+    // than what's returned by the default implementation.
+    //
+    static Level findLevel(String name) {
+        if (name == null) {
+            throw new NullPointerException();
+        }
+
+        KnownLevel level;
+
+        // Look for a known Level with the given non-localized name.
+        level = KnownLevel.findByName(name);
+        if (level != null) {
+            return level.mirroredLevel;
+        }
+
+        // Now, check if the given name is an integer.  If so,
+        // first look for a Level with the given value and then
+        // if necessary create one.
+        try {
+            int x = Integer.parseInt(name);
+            level = KnownLevel.findByValue(x);
+            if (level == null) {
+                // add new Level
+                Level levelObject = new Level(name, x);
+                level = KnownLevel.findByValue(x);
+            }
+            return level.mirroredLevel;
+        } catch (NumberFormatException ex) {
+            // Not an integer.
+            // Drop through.
+        }
+
+        level = KnownLevel.findByLocalizedLevelName(name);
+        if (level != null) {
+            return level.mirroredLevel;
+        }
+
+        return null;
     }
 
     /**
@@ -268,21 +337,15 @@
     // Serialization magic to prevent "doppelgangers".
     // This is a performance optimization.
     private Object readResolve() {
-        synchronized (Level.class) {
-            for (int i = 0; i < known.size(); i++) {
-                Level other = known.get(i);
-                if (this.name.equals(other.name) && this.value == other.value
-                        && (this.resourceBundleName == other.resourceBundleName ||
-                            (this.resourceBundleName != null &&
-                            this.resourceBundleName.equals(other.resourceBundleName)))) {
-                    return other;
-                }
-            }
-            // Woops.  Whoever sent us this object knows
-            // about a new log level.  Add it to our list.
-            known.add(this);
-            return this;
+        KnownLevel o = KnownLevel.matches(this);
+        if (o != null) {
+            return o.levelObject;
         }
+
+        // Woops.  Whoever sent us this object knows
+        // about a new log level.  Add it to our list.
+        Level level = new Level(this.name, this.value, this.resourceBundleName);
+        return level;
     }
 
     /**
@@ -296,6 +359,7 @@
      * <li>     "SEVERE"
      * <li>     "1000"
      * </ul>
+     *
      * @param  name   string to be parsed
      * @throws NullPointerException if the name is null
      * @throws IllegalArgumentException if the value is not valid.
@@ -315,12 +379,12 @@
         // Check that name is not null.
         name.length();
 
+        KnownLevel level;
+
         // Look for a known Level with the given non-localized name.
-        for (int i = 0; i < known.size(); i++) {
-            Level l = known.get(i);
-            if (name.equals(l.name)) {
-                return l;
-            }
+        level = KnownLevel.findByName(name);
+        if (level != null) {
+            return level.levelObject;
         }
 
         // Now, check if the given name is an integer.  If so,
@@ -328,14 +392,13 @@
         // if necessary create one.
         try {
             int x = Integer.parseInt(name);
-            for (int i = 0; i < known.size(); i++) {
-                Level l = known.get(i);
-                if (l.value == x) {
-                    return l;
-                }
+            level = KnownLevel.findByValue(x);
+            if (level == null) {
+                // add new Level
+                Level levelObject = new Level(name, x);
+                level = KnownLevel.findByValue(x);
             }
-            // Create a new Level.
-            return new Level(name, x);
+            return level.levelObject;
         } catch (NumberFormatException ex) {
             // Not an integer.
             // Drop through.
@@ -344,11 +407,9 @@
         // Finally, look for a known level with the given localized name,
         // in the current default locale.
         // This is relatively expensive, but not excessively so.
-        for (int i = 0; i < known.size(); i++) {
-            Level l =  known.get(i);
-            if (name.equals(l.getLocalizedName())) {
-                return l;
-            }
+        level = KnownLevel.findByLocalizedName(name);
+        if (level != null) {
+            return level.levelObject;
         }
 
         // OK, we've tried everything and failed
@@ -375,4 +436,124 @@
     public int hashCode() {
         return this.value;
     }
+
+    // KnownLevel class maintains the global list of all known levels.
+    // The API allows multiple custom Level instances of the same name/value
+    // be created. This class provides convenient methods to find a level
+    // by a given name, by a given value, or by a given localized name.
+    //
+    // KnownLevel wraps the following Level objects:
+    // 1. levelObject:   standard Level object or custom Level object
+    // 2. mirroredLevel: Level object representing the level specified in the
+    //                   logging configuration.
+    //
+    // Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
+    // are non-final but the name and resource bundle name are parameters to
+    // the Level constructor.  Use the mirroredLevel object instead of the
+    // levelObject to prevent the logging framework to execute foreign code
+    // implemented by untrusted Level subclass.
+    //
+    // Implementation Notes:
+    // If Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
+    // were final, the following KnownLevel implementation can be removed.
+    // Future API change should take this into consideration.
+    static final class KnownLevel {
+        private static Map<String, List<KnownLevel>> nameToLevels = new HashMap<>();
+        private static Map<Integer, List<KnownLevel>> intToLevels = new HashMap<>();
+        final Level levelObject;     // instance of Level class or Level subclass
+        final Level mirroredLevel;   // instance of Level class
+        KnownLevel(Level l) {
+            this.levelObject = l;
+            if (l.getClass() == Level.class) {
+                this.mirroredLevel = l;
+            } else {
+                this.mirroredLevel = new Level(l.name, l.value, l.resourceBundleName);
+            }
+        }
+
+        static synchronized void add(Level l) {
+            // the mirroredLevel object is always added to the list
+            // before the custom Level instance
+            KnownLevel o = new KnownLevel(l);
+            List<KnownLevel> list = nameToLevels.get(l.name);
+            if (list == null) {
+                list = new ArrayList<>();
+                nameToLevels.put(l.name, list);
+            }
+            list.add(o);
+
+            list = intToLevels.get(l.value);
+            if (list == null) {
+                list = new ArrayList<>();
+                intToLevels.put(l.value, list);
+            }
+            list.add(o);
+        }
+
+        // Returns a KnownLevel with the given non-localized name.
+        static synchronized KnownLevel findByName(String name) {
+            List<KnownLevel> list = nameToLevels.get(name);
+            if (list != null) {
+                return list.get(0);
+            }
+            return null;
+        }
+
+        // Returns a KnownLevel with the given value.
+        static synchronized KnownLevel findByValue(int value) {
+            List<KnownLevel> list = intToLevels.get(value);
+            if (list != null) {
+                return list.get(0);
+            }
+            return null;
+        }
+
+        // Returns a KnownLevel with the given localized name matching
+        // by calling the Level.getLocalizedLevelName() method (i.e. found
+        // from the resourceBundle associated with the Level object).
+        // This method does not call Level.getLocalizedName() that may
+        // be overridden in a subclass implementation
+        static synchronized KnownLevel findByLocalizedLevelName(String name) {
+            for (List<KnownLevel> levels : nameToLevels.values()) {
+                for (KnownLevel l : levels) {
+                    String lname = l.levelObject.getLocalizedLevelName();
+                    if (name.equals(lname)) {
+                        return l;
+                    }
+                }
+            }
+            return null;
+        }
+
+        // Returns a KnownLevel with the given localized name matching
+        // by calling the Level.getLocalizedName() method
+        static synchronized KnownLevel findByLocalizedName(String name) {
+            for (List<KnownLevel> levels : nameToLevels.values()) {
+                for (KnownLevel l : levels) {
+                    String lname = l.levelObject.getLocalizedName();
+                    if (name.equals(lname)) {
+                        return l;
+                    }
+                }
+            }
+            return null;
+        }
+
+        static synchronized KnownLevel matches(Level l) {
+            List<KnownLevel> list = nameToLevels.get(l.name);
+            if (list != null) {
+                for (KnownLevel level : list) {
+                    Level other = level.mirroredLevel;
+                    if (l.value == other.value &&
+                           (l.resourceBundleName == other.resourceBundleName ||
+                               (l.resourceBundleName != null &&
+                                l.resourceBundleName.equals(other.resourceBundleName)))) {
+                        return level;
+                    }
+                }
+            }
+            return null;
+        }
+    }
+
 }
--- a/src/share/classes/java/util/logging/LogManager.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/util/logging/LogManager.java	Mon Feb 25 08:44:00 2013 +0100
@@ -35,6 +35,10 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.beans.PropertyChangeListener;
+import java.net.URL;
+import sun.misc.JavaAWTAccess;
+import sun.misc.SharedSecrets;
+import sun.security.action.GetPropertyAction;
 
 /**
  * There is a single global LogManager object that is used to
@@ -152,10 +156,9 @@
     // count to allow for cases where the same listener is registered many times.
     private final Map<Object,Integer> listenerMap = new HashMap<>();
 
-    // Table of named Loggers that maps names to Loggers.
-    private Hashtable<String,LoggerWeakRef> namedLoggers = new Hashtable<>();
-    // Tree of named Loggers
-    private LogNode root = new LogNode(null);
+    // LoggerContext for system loggers and user loggers
+    private final LoggerContext systemContext = new SystemLoggerContext();
+    private final LoggerContext userContext = new LoggerContext();
     private Logger rootLogger;
 
     // Have we done the primordial reading of the configuration file?
@@ -194,11 +197,12 @@
                     // Create and retain Logger for the root of the namespace.
                     manager.rootLogger = manager.new RootLogger();
                     manager.addLogger(manager.rootLogger);
+                    manager.systemContext.addLocalLogger(manager.rootLogger);
 
                     // Adding the global Logger. Doing so in the Logger.<clinit>
                     // would deadlock with the LogManager.<clinit>.
-                    Logger.getGlobal().setLogManager(manager);
-                    manager.addLogger(Logger.getGlobal());
+                    Logger.global.setLogManager(manager);
+                    manager.addLogger(Logger.global);
 
                     // We don't call readConfiguration() here, as we may be running
                     // very early in the JVM startup sequence.  Instead readConfiguration
@@ -276,14 +280,14 @@
                         return;
                     }
                     readPrimordialConfiguration = true;
+
                     try {
-                        AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
-                                public Object run() throws Exception {
+                        AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
+                                public Void run() throws Exception {
                                     readConfiguration();
 
                                     // Platform loggers begin to delegate to java.util.logging.Logger
                                     sun.util.logging.PlatformLogger.redirectPlatformLoggers();
-
                                     return null;
                                 }
                             });
@@ -375,20 +379,68 @@
         }
     }
 
-    // Package-level method.
+    // Returns the LoggerContext for the user code (i.e. application or AppContext).
+    // Loggers are isolated from each AppContext.
+    private LoggerContext getUserContext() {
+        LoggerContext context = null;
+
+        SecurityManager sm = System.getSecurityManager();
+        JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess();
+        if (sm != null && javaAwtAccess != null) {
+            synchronized (javaAwtAccess) {
+                // AppContext.getAppContext() returns the system AppContext if called
+                // from a system thread but Logger.getLogger might be called from
+                // an applet code. Instead, find the AppContext of the applet code
+                // from the execution stack.
+                Object ecx = javaAwtAccess.getExecutionContext();
+                if (ecx == null) {
+                    // fall back to AppContext.getAppContext()
+                    ecx = javaAwtAccess.getContext();
+                }
+                context = (LoggerContext)javaAwtAccess.get(ecx, LoggerContext.class);
+                if (context == null) {
+                    if (javaAwtAccess.isMainAppContext()) {
+                        context = userContext;
+                    } else {
+                        context = new LoggerContext();
+                        // during initialization, rootLogger is null when
+                        // instantiating itself RootLogger
+                        if (manager.rootLogger != null)
+                            context.addLocalLogger(manager.rootLogger);
+                    }
+                    javaAwtAccess.put(ecx, LoggerContext.class, context);
+                }
+            }
+        } else {
+            context = userContext;
+        }
+        return context;
+    }
+
+    private List<LoggerContext> contexts() {
+        List<LoggerContext> cxs = new ArrayList<>();
+        cxs.add(systemContext);
+        cxs.add(getUserContext());
+        return cxs;
+    }
+
     // Find or create a specified logger instance. If a logger has
     // already been created with the given name it is returned.
     // Otherwise a new logger instance is created and registered
     // in the LogManager global namespace.
-
     // This method will always return a non-null Logger object.
     // Synchronization is not required here. All synchronization for
     // adding a new Logger object is handled by addLogger().
-    Logger demandLogger(String name) {
+    //
+    // This method must delegate to the LogManager implementation to
+    // add a new Logger or return the one that has been added previously
+    // as a LogManager subclass may override the addLogger, getLogger,
+    // readConfiguration, and other methods.
+    Logger demandLogger(String name, String resourceBundleName) {
         Logger result = getLogger(name);
         if (result == null) {
             // only allocate the new logger once
-            Logger newLogger = new Logger(name, null);
+            Logger newLogger = new Logger(name, resourceBundleName);
             do {
                 if (addLogger(newLogger)) {
                     // We successfully added the new Logger that we
@@ -413,24 +465,249 @@
         return result;
     }
 
-    // If logger.getUseParentHandlers() returns 'true' and any of the logger's
-    // parents have levels or handlers defined, make sure they are instantiated.
-    private void processParentHandlers(Logger logger, String name) {
-        int ix = 1;
-        for (;;) {
-            int ix2 = name.indexOf(".", ix);
-            if (ix2 < 0) {
-                break;
+    Logger demandSystemLogger(String name, String resourceBundleName) {
+        // Add a system logger in the system context's namespace
+        final Logger sysLogger = systemContext.demandLogger(name, resourceBundleName);
+
+        // Add the system logger to the LogManager's namespace if not exist
+        // so that there is only one single logger of the given name.
+        // System loggers are visible to applications unless a logger of
+        // the same name has been added.
+        Logger logger;
+        do {
+            // First attempt to call addLogger instead of getLogger
+            // This would avoid potential bug in custom LogManager.getLogger
+            // implementation that adds a logger if does not exist
+            if (addLogger(sysLogger)) {
+                // successfully added the new system logger
+                logger = sysLogger;
+            } else {
+                logger = getLogger(name);
             }
-            String pname = name.substring(0,ix2);
+        } while (logger == null);
 
-            if (getProperty(pname+".level")    != null ||
-                getProperty(pname+".handlers") != null) {
-                // This pname has a level/handlers definition.
-                // Make sure it exists.
-                demandLogger(pname);
+        // LogManager will set the sysLogger's handlers via LogManager.addLogger method.
+        if (logger != sysLogger && sysLogger.getHandlers().length == 0) {
+            // if logger already exists but handlers not set
+            final Logger l = logger;
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    for (Handler hdl : l.getHandlers()) {
+                        sysLogger.addHandler(hdl);
+                    }
+                    return null;
+                }
+            });
+        }
+        return sysLogger;
+    }
+
+    // LoggerContext maintains the logger namespace per context.
+    // The default LogManager implementation has one system context and user
+    // context.  The system context is used to maintain the namespace for
+    // all system loggers and is queried by the system code.  If a system logger
+    // doesn't exist in the user context, it'll also be added to the user context.
+    // The user context is queried by the user code and all other loggers are
+    // added in the user context.
+    static class LoggerContext {
+        // Table of named Loggers that maps names to Loggers.
+        private final Hashtable<String,LoggerWeakRef> namedLoggers = new Hashtable<>();
+        // Tree of named Loggers
+        private final LogNode root;
+
+        private LoggerContext() {
+            this.root = new LogNode(null, this);
+        }
+
+        Logger demandLogger(String name, String resourceBundleName) {
+            // a LogManager subclass may have its own implementation to add and
+            // get a Logger.  So delegate to the LogManager to do the work.
+            return manager.demandLogger(name, resourceBundleName);
+        }
+
+        synchronized Logger findLogger(String name) {
+            LoggerWeakRef ref = namedLoggers.get(name);
+            if (ref == null) {
+                return null;
             }
-            ix = ix2+1;
+            Logger logger = ref.get();
+            if (logger == null) {
+                // Hashtable holds stale weak reference
+                // to a logger which has been GC-ed.
+                removeLogger(name);
+            }
+            return logger;
+        }
+
+        // Add a logger to this context.  This method will only set its level
+        // and process parent loggers.  It doesn't set its handlers.
+        synchronized boolean addLocalLogger(Logger logger) {
+            final String name = logger.getName();
+            if (name == null) {
+                throw new NullPointerException();
+            }
+
+            // cleanup some Loggers that have been GC'ed
+            manager.drainLoggerRefQueueBounded();
+
+            LoggerWeakRef ref = namedLoggers.get(name);
+            if (ref != null) {
+                if (ref.get() == null) {
+                    // It's possible that the Logger was GC'ed after the
+                    // drainLoggerRefQueueBounded() call above so allow
+                    // a new one to be registered.
+                    removeLogger(name);
+                } else {
+                    // We already have a registered logger with the given name.
+                    return false;
+                }
+            }
+
+            // We're adding a new logger.
+            // Note that we are creating a weak reference here.
+            ref = manager.new LoggerWeakRef(logger);
+            namedLoggers.put(name, ref);
+
+            // Apply any initial level defined for the new logger.
+            Level level = manager.getLevelProperty(name + ".level", null);
+            if (level != null) {
+                doSetLevel(logger, level);
+            }
+
+            // instantiation of the handler is done in the LogManager.addLogger
+            // implementation as a handler class may be only visible to LogManager
+            // subclass for the custom log manager case
+            processParentHandlers(logger, name);
+
+            // Find the new node and its parent.
+            LogNode node = getNode(name);
+            node.loggerRef = ref;
+            Logger parent = null;
+            LogNode nodep = node.parent;
+            while (nodep != null) {
+                LoggerWeakRef nodeRef = nodep.loggerRef;
+                if (nodeRef != null) {
+                    parent = nodeRef.get();
+                    if (parent != null) {
+                        break;
+                    }
+                }
+                nodep = nodep.parent;
+            }
+
+            if (parent != null) {
+                doSetParent(logger, parent);
+            }
+            // Walk over the children and tell them we are their new parent.
+            node.walkAndSetParent(logger);
+            // new LogNode is ready so tell the LoggerWeakRef about it
+            ref.setNode(node);
+            return true;
+        }
+
+        void removeLogger(String name) {
+            namedLoggers.remove(name);
+        }
+
+        synchronized Enumeration<String> getLoggerNames() {
+            return namedLoggers.keys();
+        }
+
+        // If logger.getUseParentHandlers() returns 'true' and any of the logger's
+        // parents have levels or handlers defined, make sure they are instantiated.
+        private void processParentHandlers(final Logger logger, final String name) {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    if (logger != manager.rootLogger) {
+                        boolean useParent = manager.getBooleanProperty(name + ".useParentHandlers", true);
+                        if (!useParent) {
+                            logger.setUseParentHandlers(false);
+                        }
+                    }
+                    return null;
+                }
+            });
+
+            int ix = 1;
+            for (;;) {
+                int ix2 = name.indexOf(".", ix);
+                if (ix2 < 0) {
+                    break;
+                }
+                String pname = name.substring(0, ix2);
+                if (manager.getProperty(pname + ".level") != null ||
+                    manager.getProperty(pname + ".handlers") != null) {
+                    // This pname has a level/handlers definition.
+                    // Make sure it exists.
+                    demandLogger(pname, null);
+                }
+                ix = ix2+1;
+            }
+        }
+
+        // Gets a node in our tree of logger nodes.
+        // If necessary, create it.
+        LogNode getNode(String name) {
+            if (name == null || name.equals("")) {
+                return root;
+            }
+            LogNode node = root;
+            while (name.length() > 0) {
+                int ix = name.indexOf(".");
+                String head;
+                if (ix > 0) {
+                    head = name.substring(0, ix);
+                    name = name.substring(ix + 1);
+                } else {
+                    head = name;
+                    name = "";
+                }
+                if (node.children == null) {
+                    node.children = new HashMap<>();
+                }
+                LogNode child = node.children.get(head);
+                if (child == null) {
+                    child = new LogNode(node, this);
+                    node.children.put(head, child);
+                }
+                node = child;
+            }
+            return node;
+        }
+    }
+
+    static class SystemLoggerContext extends LoggerContext {
+        // Add a system logger in the system context's namespace as well as
+        // in the LogManager's namespace if not exist so that there is only
+        // one single logger of the given name.  System loggers are visible
+        // to applications unless a logger of the same name has been added.
+        Logger demandLogger(String name, String resourceBundleName) {
+            Logger result = findLogger(name);
+            if (result == null) {
+                // only allocate the new system logger once
+                Logger newLogger = new Logger(name, resourceBundleName);
+                do {
+                    if (addLocalLogger(newLogger)) {
+                        // We successfully added the new Logger that we
+                        // created above so return it without refetching.
+                        result = newLogger;
+                    } else {
+                        // We didn't add the new Logger that we created above
+                        // because another thread added a Logger with the same
+                        // name after our null check above and before our call
+                        // to addLogger(). We have to refetch the Logger because
+                        // addLogger() returns a boolean instead of the Logger
+                        // reference itself. However, if the thread that created
+                        // the other Logger is not holding a strong reference to
+                        // the other Logger, then it is possible for the other
+                        // Logger to be GC'ed after we saw it in addLogger() and
+                        // before we can refetch it. If it has been GC'ed then
+                        // we'll just loop around and try again.
+                        result = findLogger(name);
+                    }
+                } while (result == null);
+            }
+            return result;
         }
     }
 
@@ -439,32 +716,27 @@
     // be made based on the logging configuration, which can
     // only be modified by trusted code.
     private void loadLoggerHandlers(final Logger logger, final String name,
-                                    final String handlersPropertyName) {
+                                    final String handlersPropertyName)
+    {
         AccessController.doPrivileged(new PrivilegedAction<Object>() {
             public Object run() {
-                if (logger != rootLogger) {
-                    boolean useParent = getBooleanProperty(name + ".useParentHandlers", true);
-                    if (!useParent) {
-                        logger.setUseParentHandlers(false);
-                    }
-                }
-
                 String names[] = parseClassNames(handlersPropertyName);
                 for (int i = 0; i < names.length; i++) {
                     String word = names[i];
                     try {
                         Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(word);
-                        Handler  hdl = (Handler) clz.newInstance();
-                        try {
-                            // Check if there is a property defining the
-                            // this handler's level.
-                            String levs = getProperty(word + ".level");
-                            if (levs != null) {
-                                hdl.setLevel(Level.parse(levs));
+                        Handler hdl = (Handler) clz.newInstance();
+                        // Check if there is a property defining the
+                        // this handler's level.
+                        String levs = getProperty(word + ".level");
+                        if (levs != null) {
+                            Level l = Level.findLevel(levs);
+                            if (l != null) {
+                                hdl.setLevel(l);
+                            } else {
+                                // Probably a bad level. Drop through.
+                                System.err.println("Can't set level for " + word);
                             }
-                        } catch (Exception ex) {
-                            System.err.println("Can't set level for " + word);
-                            // Probably a bad level. Drop through.
                         }
                         // Add this Handler to the logger
                         logger.addHandler(hdl);
@@ -475,7 +747,8 @@
                     }
                 }
                 return null;
-            }});
+            }
+        });
     }
 
 
@@ -520,7 +793,7 @@
             if (node != null) {
                 // if we have a LogNode, then we were a named Logger
                 // so clear namedLoggers weak ref to us
-                manager.namedLoggers.remove(name);
+                node.context.removeLogger(name);
                 name = null;  // clear our ref to the Logger's name
 
                 node.loggerRef = null;  // clear LogNode's weak ref to us
@@ -609,73 +882,22 @@
      *          false if a logger of that name already exists.
      * @exception NullPointerException if the logger name is null.
      */
-    public synchronized boolean addLogger(Logger logger) {
+    public boolean addLogger(Logger logger) {
         final String name = logger.getName();
         if (name == null) {
             throw new NullPointerException();
         }
-
-        // cleanup some Loggers that have been GC'ed
-        drainLoggerRefQueueBounded();
-
-        LoggerWeakRef ref = namedLoggers.get(name);
-        if (ref != null) {
-            if (ref.get() == null) {
-                // It's possible that the Logger was GC'ed after the
-                // drainLoggerRefQueueBounded() call above so allow
-                // a new one to be registered.
-                namedLoggers.remove(name);
-            } else {
-                // We already have a registered logger with the given name.
-                return false;
-            }
+        LoggerContext cx = getUserContext();
+        if (cx.addLocalLogger(logger)) {
+            // Do we have a per logger handler too?
+            // Note: this will add a 200ms penalty
+            loadLoggerHandlers(logger, name, name + ".handlers");
+            return true;
+        } else {
+            return false;
         }
-
-        // We're adding a new logger.
-        // Note that we are creating a weak reference here.
-        ref = new LoggerWeakRef(logger);
-        namedLoggers.put(name, ref);
-
-        // Apply any initial level defined for the new logger.
-        Level level = getLevelProperty(name+".level", null);
-        if (level != null) {
-            doSetLevel(logger, level);
-        }
-
-        // Do we have a per logger handler too?
-        // Note: this will add a 200ms penalty
-        loadLoggerHandlers(logger, name, name+".handlers");
-        processParentHandlers(logger, name);
-
-        // Find the new node and its parent.
-        LogNode node = findNode(name);
-        node.loggerRef = ref;
-        Logger parent = null;
-        LogNode nodep = node.parent;
-        while (nodep != null) {
-            LoggerWeakRef nodeRef = nodep.loggerRef;
-            if (nodeRef != null) {
-                parent = nodeRef.get();
-                if (parent != null) {
-                    break;
-                }
-            }
-            nodep = nodep.parent;
-        }
-
-        if (parent != null) {
-            doSetParent(logger, parent);
-        }
-        // Walk over the children and tell them we are their new parent.
-        node.walkAndSetParent(logger);
-
-        // new LogNode is ready so tell the LoggerWeakRef about it
-        ref.setNode(node);
-
-        return true;
     }
 
-
     // Private method to set a level on a logger.
     // If necessary, we raise privilege before doing the call.
     private static void doSetLevel(final Logger logger, final Level level) {
@@ -694,8 +916,6 @@
             }});
     }
 
-
-
     // Private method to set a parent on a logger.
     // If necessary, we raise privilege before doing the setParent call.
     private static void doSetParent(final Logger logger, final Logger parent) {
@@ -714,36 +934,6 @@
             }});
     }
 
-    // Find a node in our tree of logger nodes.
-    // If necessary, create it.
-    private LogNode findNode(String name) {
-        if (name == null || name.equals("")) {
-            return root;
-        }
-        LogNode node = root;
-        while (name.length() > 0) {
-            int ix = name.indexOf(".");
-            String head;
-            if (ix > 0) {
-                head = name.substring(0,ix);
-                name = name.substring(ix+1);
-            } else {
-                head = name;
-                name = "";
-            }
-            if (node.children == null) {
-                node.children = new HashMap<>();
-            }
-            LogNode child = node.children.get(head);
-            if (child == null) {
-                child = new LogNode(node);
-                node.children.put(head, child);
-            }
-            node = child;
-        }
-        return node;
-    }
-
     /**
      * Method to find a named logger.
      * <p>
@@ -759,18 +949,8 @@
      * @param name name of the logger
      * @return  matching logger or null if none is found
      */
-    public synchronized Logger getLogger(String name) {
-        LoggerWeakRef ref = namedLoggers.get(name);
-        if (ref == null) {
-            return null;
-        }
-        Logger logger = ref.get();
-        if (logger == null) {
-            // Hashtable holds stale weak reference
-            // to a logger which has been GC-ed.
-            namedLoggers.remove(name);
-        }
-        return logger;
+    public Logger getLogger(String name) {
+        return getUserContext().findLogger(name);
     }
 
     /**
@@ -789,8 +969,8 @@
      * <p>
      * @return  enumeration of logger name strings
      */
-    public synchronized Enumeration<String> getLoggerNames() {
-        return namedLoggers.keys();
+    public Enumeration<String> getLoggerNames() {
+        return getUserContext().getLoggerNames();
     }
 
     /**
@@ -875,20 +1055,20 @@
             // the global handlers, if they haven't been initialized yet.
             initializedGlobalHandlers = true;
         }
-        Enumeration<String> enum_ = getLoggerNames();
-        while (enum_.hasMoreElements()) {
-            String name = enum_.nextElement();
-            resetLogger(name);
+        for (LoggerContext cx : contexts()) {
+            Enumeration<String> enum_ = cx.getLoggerNames();
+            while (enum_.hasMoreElements()) {
+                String name = enum_.nextElement();
+                Logger logger = cx.findLogger(name);
+                if (logger != null) {
+                    resetLogger(logger);
+                }
+            }
         }
     }
 
-
     // Private method to reset an individual target logger.
-    private void resetLogger(String name) {
-        Logger logger = getLogger(name);
-        if (logger == null) {
-            return;
-        }
+    private void resetLogger(Logger logger) {
         // Close all the Logger's handlers.
         Handler[] targets = logger.getHandlers();
         for (int i = 0; i < targets.length; i++) {
@@ -900,6 +1080,7 @@
                 // Problems closing a handler?  Keep going...
             }
         }
+        String name = logger.getName();
         if (name != null && name.equals("")) {
             // This is the root logger.
             logger.setLevel(defaultLevel);
@@ -1065,11 +1246,8 @@
         if (val == null) {
             return defaultValue;
         }
-        try {
-            return Level.parse(val.trim());
-        } catch (Exception ex) {
-            return defaultValue;
-        }
+        Level l = Level.findLevel(val.trim());
+        return l != null ? l : defaultValue;
     }
 
     // Package private method to get a filter property.
@@ -1159,9 +1337,11 @@
         HashMap<String,LogNode> children;
         LoggerWeakRef loggerRef;
         LogNode parent;
+        final LoggerContext context;
 
-        LogNode(LogNode parent) {
+        LogNode(LogNode parent, LoggerContext context) {
             this.parent = parent;
+            this.context = context;
         }
 
         // Recursive method to walk the tree below a node and set
@@ -1188,7 +1368,6 @@
     // that we only instantiate the global handlers when they
     // are first needed.
     private class RootLogger extends Logger {
-
         private RootLogger() {
             super("", null);
             setLevel(defaultLevel);
@@ -1234,11 +1413,13 @@
                 System.err.println("Bad level value for property: " + key);
                 continue;
             }
-            Logger l = getLogger(name);
-            if (l == null) {
-                continue;
+            for (LoggerContext cx : contexts()) {
+                Logger l = cx.findLogger(name);
+                if (l == null) {
+                    continue;
+                }
+                l.setLevel(level);
             }
-            l.setLevel(level);
         }
     }
 
--- a/src/share/classes/java/util/logging/Logger.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/util/logging/Logger.java	Mon Feb 25 08:44:00 2013 +0100
@@ -314,6 +314,40 @@
         }
     }
 
+    // Until all JDK code converted to call sun.util.logging.PlatformLogger
+    // (see 7054233), we need to determine if Logger.getLogger is to add
+    // a system logger or user logger.
+    //
+    // As an interim solution, if the immediate caller whose caller loader is
+    // null, we assume it's a system logger and add it to the system context.
+    // These system loggers only set the resource bundle to the given
+    // resource bundle name (rather than the default system resource bundle).
+    private static class SystemLoggerHelper {
+        static boolean disableCallerCheck = getBooleanProperty("sun.util.logging.disableCallerCheck");
+        private static boolean getBooleanProperty(final String key) {
+            String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty(key);
+                }
+            });
+            return Boolean.valueOf(s);
+        }
+    }
+
+    private static Logger demandLogger(String name, String resourceBundleName) {
+        LogManager manager = LogManager.getLogManager();
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null && !SystemLoggerHelper.disableCallerCheck) {
+            // 0: Reflection 1: Logger.demandLogger 2: Logger.getLogger 3: caller
+            final int SKIP_FRAMES = 3;
+            Class<?> caller = sun.reflect.Reflection.getCallerClass(SKIP_FRAMES);
+            if (caller.getClassLoader() == null) {
+                return manager.demandSystemLogger(name, resourceBundleName);
+            }
+        }
+        return manager.demandLogger(name, resourceBundleName);
+    }
+
     /**
      * Find or create a logger for a named subsystem.  If a logger has
      * already been created with the given name it is returned.  Otherwise
@@ -355,8 +389,7 @@
         // would throw an IllegalArgumentException in the second call
         // because the wrapper would result in an attempt to replace
         // the existing "resourceBundleForFoo" with null.
-        LogManager manager = LogManager.getLogManager();
-        return manager.demandLogger(name);
+        return demandLogger(name, null);
     }
 
     /**
@@ -403,8 +436,7 @@
     // Synchronization is not required here. All synchronization for
     // adding a new Logger object is handled by LogManager.addLogger().
     public static Logger getLogger(String name, String resourceBundleName) {
-        LogManager manager = LogManager.getLogManager();
-        Logger result = manager.demandLogger(name);
+        Logger result = demandLogger(name, resourceBundleName);
 
         // MissingResourceException or IllegalArgumentException can be
         // thrown by setupResourceInfo().
@@ -412,6 +444,17 @@
         return result;
     }
 
+    // package-private
+    // Add a platform logger to the system context.
+    // i.e. caller of sun.util.logging.PlatformLogger.getLogger
+    static Logger getPlatformLogger(String name) {
+        LogManager manager = LogManager.getLogManager();
+
+        // all loggers in the system context will default to
+        // the system logger's resource bundle
+        Logger result = manager.demandSystemLogger(name, SYSTEM_LOGGER_RB_NAME);
+        return result;
+    }
 
     /**
      * Create an anonymous Logger.  The newly created Logger is not
@@ -564,7 +607,7 @@
     private void doLog(LogRecord lr) {
         lr.setLoggerName(name);
         String ebname = getEffectiveResourceBundleName();
-        if (ebname != null) {
+        if (ebname != null && !ebname.equals(SYSTEM_LOGGER_RB_NAME)) {
             lr.setResourceBundleName(ebname);
             lr.setResourceBundle(findResourceBundle(ebname));
         }
@@ -1547,6 +1590,23 @@
     // May also return null if we can't find the resource bundle and
     // there is no suitable previous cached value.
 
+    static final String SYSTEM_LOGGER_RB_NAME = "sun.util.logging.resources.logging";
+
+    private static ResourceBundle findSystemResourceBundle(final Locale locale) {
+        // the resource bundle is in a restricted package
+        return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
+            public ResourceBundle run() {
+                try {
+                    return ResourceBundle.getBundle(SYSTEM_LOGGER_RB_NAME,
+                                                    locale,
+                                                    ClassLoader.getSystemClassLoader());
+                } catch (MissingResourceException e) {
+                    throw new InternalError(e.toString());
+                }
+            }
+        });
+    }
+
     private synchronized ResourceBundle findResourceBundle(String name) {
         // Return a null bundle for a null name.
         if (name == null) {
@@ -1561,6 +1621,13 @@
             return catalog;
         }
 
+        if (name.equals(SYSTEM_LOGGER_RB_NAME)) {
+            catalog = findSystemResourceBundle(currentLocale);
+            catalogName = name;
+            catalogLocale = currentLocale;
+            return catalog;
+        }
+
         // Use the thread's context ClassLoader.  If there isn't one,
         // use the SystemClassloader.
         ClassLoader cl = Thread.currentThread().getContextClassLoader();
@@ -1577,7 +1644,6 @@
             // ClassLoader.  Drop through.
         }
 
-
         // Fall back to searching up the call stack and trying each
         // calling ClassLoader.
         for (int ix = 0; ; ix++) {
--- a/src/share/classes/java/util/logging/Logging.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/util/logging/Logging.java	Mon Feb 25 08:44:00 2013 +0100
@@ -34,7 +34,7 @@
  *
  * The <tt>LoggingMXBean</tt> interface provides a standard
  * method for management access to the individual
- * java.util.Logger objects available at runtime.
+ * {@code Logger} objects available at runtime.
  *
  * @author Ron Mann
  * @author Mandy Chung
@@ -75,7 +75,7 @@
         if (level == null) {
             return EMPTY_STRING;
         } else {
-            return level.getName();
+            return level.getLevelName();
         }
     }
 
@@ -85,7 +85,6 @@
         }
 
         Logger logger = logManager.getLogger(loggerName);
-
         if (logger == null) {
             throw new IllegalArgumentException("Logger " + loggerName +
                 "does not exist");
@@ -94,7 +93,10 @@
         Level level = null;
         if (levelName != null) {
             // parse will throw IAE if logLevel is invalid
-            level = Level.parse(levelName);
+            level = Level.findLevel(levelName);
+            if (level == null) {
+                throw new IllegalArgumentException("Unknown level \"" + levelName + "\"");
+            }
         }
 
         logger.setLevel(level);
--- a/src/share/classes/java/util/logging/LoggingProxyImpl.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/util/logging/LoggingProxyImpl.java	Mon Feb 25 08:44:00 2013 +0100
@@ -37,7 +37,8 @@
 
     @Override
     public Object getLogger(String name) {
-        return Logger.getLogger(name);
+        // always create a platform logger with the resource bundle name
+        return Logger.getPlatformLogger(name);
     }
 
     @Override
@@ -92,12 +93,16 @@
 
     @Override
     public Object parseLevel(String levelName) {
-        return Level.parse(levelName);
+        Level level = Level.findLevel(levelName);
+        if (level == null) {
+            throw new IllegalArgumentException("Unknown level \"" + levelName + "\"");
+        }
+        return level;
     }
 
     @Override
     public String getLevelName(Object level) {
-        return ((Level) level).getName();
+        return ((Level) level).getLevelName();
     }
 
     @Override
--- a/src/share/classes/java/util/logging/SimpleFormatter.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/java/util/logging/SimpleFormatter.java	Mon Feb 25 08:44:00 2013 +0100
@@ -162,7 +162,7 @@
                              dat,
                              source,
                              record.getLoggerName(),
-                             record.getLevel().getLocalizedName(),
+                             record.getLevel().getLocalizedLevelName(),
                              message,
                              throwable);
     }
--- a/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -39,11 +39,13 @@
 import java.lang.reflect.InvocationTargetException;
 
 import java.lang.reflect.Method;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.logging.Level;
 import java.util.Map;
 import java.util.Set;
@@ -78,6 +80,8 @@
 import javax.management.RuntimeOperationsException;
 import javax.management.ServiceNotFoundException;
 import javax.management.loading.ClassLoaderRepository;
+import sun.misc.JavaSecurityAccess;
+import sun.misc.SharedSecrets;
 
 import sun.reflect.misc.MethodUtil;
 import sun.reflect.misc.ReflectUtil;
@@ -138,6 +142,9 @@
     private boolean registered = false;
     private transient MBeanServer server = null;
 
+    private final static JavaSecurityAccess javaSecurityAccess = SharedSecrets.getJavaSecurityAccess();
+    final private AccessControlContext acc = AccessController.getContext();
+
     /*************************************/
     /* constructors                      */
     /*************************************/
@@ -1025,10 +1032,31 @@
 
             if (opClassName != null) {
                 try {
-                    final ClassLoader targetClassLoader =
-                        targetObject.getClass().getClassLoader();
-                    targetClass = Class.forName(opClassName, false,
-                                                targetClassLoader);
+                    AccessControlContext stack = AccessController.getContext();
+                    final Object obj = targetObject;
+                    final String className = opClassName;
+                    final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
+
+                    targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
+
+                        @Override
+                        public Class<?> run() {
+                            try {
+                                ReflectUtil.checkPackageAccess(className);
+                                final ClassLoader targetClassLoader =
+                                    obj.getClass().getClassLoader();
+                                return Class.forName(className, false,
+                                                            targetClassLoader);
+                            } catch (ClassNotFoundException e) {
+                                caughtException[0] = e;
+                            }
+                            return null;
+                        }
+                    }, stack, acc);
+
+                    if (caughtException[0] != null) {
+                        throw caughtException[0];
+                    }
                 } catch (ClassNotFoundException e) {
                     final String msg =
                         "class for invoke " + opName + " not found";
@@ -1061,9 +1089,9 @@
         return result;
     }
 
-    private static Method resolveMethod(Class<?> targetClass,
+    private Method resolveMethod(Class<?> targetClass,
                                         String opMethodName,
-                                        String[] sig)
+                                        final String[] sig)
             throws ReflectionException {
         final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
 
@@ -1078,30 +1106,45 @@
         if (sig == null)
             argClasses = null;
         else {
+            final AccessControlContext stack = AccessController.getContext();
+            final ReflectionException[] caughtException = new ReflectionException[1];
             final ClassLoader targetClassLoader = targetClass.getClassLoader();
             argClasses = new Class<?>[sig.length];
-            for (int i = 0; i < sig.length; i++) {
-                if (tracing) {
-                    MODELMBEAN_LOGGER.logp(Level.FINER,
-                        RequiredModelMBean.class.getName(),"resolveMethod",
-                            "resolve type " + sig[i]);
-                }
-                argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]);
-                if (argClasses[i] == null) {
-                    try {
-                        argClasses[i] =
-                            Class.forName(sig[i], false, targetClassLoader);
-                    } catch (ClassNotFoundException e) {
+
+            javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
+
+                @Override
+                public Void run() {
+                    for (int i = 0; i < sig.length; i++) {
                         if (tracing) {
                             MODELMBEAN_LOGGER.logp(Level.FINER,
-                                    RequiredModelMBean.class.getName(),
-                                    "resolveMethod",
-                                    "class not found");
+                                RequiredModelMBean.class.getName(),"resolveMethod",
+                                    "resolve type " + sig[i]);
                         }
-                        final String msg = "Parameter class not found";
-                        throw new ReflectionException(e, msg);
+                        argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]);
+                        if (argClasses[i] == null) {
+                            try {
+                                ReflectUtil.checkPackageAccess(sig[i]);
+                                argClasses[i] =
+                                    Class.forName(sig[i], false, targetClassLoader);
+                            } catch (ClassNotFoundException e) {
+                                if (tracing) {
+                                    MODELMBEAN_LOGGER.logp(Level.FINER,
+                                            RequiredModelMBean.class.getName(),
+                                            "resolveMethod",
+                                            "class not found");
+                                }
+                                final String msg = "Parameter class not found";
+                                caughtException[0] = new ReflectionException(e, msg);
+                            }
+                        }
                     }
+                    return null;
                 }
+            }, stack, acc);
+
+            if (caughtException[0] != null) {
+                throw caughtException[0];
             }
         }
 
@@ -1133,7 +1176,7 @@
     /* Find a method in RequiredModelMBean as determined by the given
        parameters.  Return null if there is none, or if the parameters
        exclude using it.  Called from invoke. */
-    private static Method findRMMBMethod(String opMethodName,
+    private Method findRMMBMethod(String opMethodName,
                                          Object targetObjectField,
                                          String opClassName,
                                          String[] sig) {
@@ -1155,19 +1198,29 @@
         if (opClassName == null)
             targetClass = rmmbClass;
         else {
-            try {
-                final ClassLoader targetClassLoader =
-                    rmmbClass.getClassLoader();
-                targetClass = Class.forName(opClassName, false,
-                                            targetClassLoader);
-                if (!rmmbClass.isAssignableFrom(targetClass))
-                    return null;
-            } catch (ClassNotFoundException e) {
-                return null;
-            }
+            AccessControlContext stack = AccessController.getContext();
+            final String className = opClassName;
+            targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
+
+                @Override
+                public Class<?> run() {
+                    try {
+                        ReflectUtil.checkPackageAccess(className);
+                        final ClassLoader targetClassLoader =
+                            rmmbClass.getClassLoader();
+                        Class clz = Class.forName(className, false,
+                                                    targetClassLoader);
+                        if (!rmmbClass.isAssignableFrom(clz))
+                            return null;
+                        return clz;
+                    } catch (ClassNotFoundException e) {
+                        return null;
+                    }
+                }
+            }, stack, acc);
         }
         try {
-            return resolveMethod(targetClass, opMethodName, sig);
+            return targetClass != null ? resolveMethod(targetClass, opMethodName, sig) : null;
         } catch (ReflectionException e) {
             return null;
         }
@@ -1177,12 +1230,35 @@
      * Invoke the given method, and throw the somewhat unpredictable
      * appropriate exception if the method itself gets an exception.
      */
-    private Object invokeMethod(String opName, Method method,
-                                Object targetObject, Object[] opArgs)
+    private Object invokeMethod(String opName, final Method method,
+                                final Object targetObject, final Object[] opArgs)
             throws MBeanException, ReflectionException {
         try {
-            ReflectUtil.checkPackageAccess(method.getDeclaringClass());
-            return MethodUtil.invoke(method, targetObject, opArgs);
+            final Throwable[] caughtException = new Throwable[1];
+            AccessControlContext stack = AccessController.getContext();
+            Object rslt = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Object>() {
+
+                @Override
+                public Object run() {
+                    try {
+                        ReflectUtil.checkPackageAccess(method.getDeclaringClass());
+                        return MethodUtil.invoke(method, targetObject, opArgs);
+                    } catch (InvocationTargetException e) {
+                        caughtException[0] = e;
+                    } catch (IllegalAccessException e) {
+                        caughtException[0] = e;
+                    }
+                    return null;
+                }
+            }, stack, acc);
+            if (caughtException[0] != null) {
+                if (caughtException[0] instanceof Exception) {
+                    throw (Exception)caughtException[0];
+                } else if(caughtException[0] instanceof Error) {
+                    throw (Error)caughtException[0];
+                }
+            }
+            return rslt;
         } catch (RuntimeErrorException ree) {
             throw new RuntimeOperationsException(ree,
                       "RuntimeException occurred in RequiredModelMBean "+
@@ -1567,7 +1643,7 @@
                 }
 
                 // make sure response class matches type field
-                String respType = attrInfo.getType();
+                final String respType = attrInfo.getType();
                 if (response != null) {
                     String responseClass = response.getClass().getName();
                     if (!respType.equals(responseClass)) {
@@ -1590,9 +1666,31 @@
                             // inequality may come from type subclassing
                             boolean subtype;
                             try {
-                                ClassLoader cl =
-                                    response.getClass().getClassLoader();
-                                Class<?> c = Class.forName(respType, true, cl);
+                                final Class respClass = response.getClass();
+                                final Exception[] caughException = new Exception[1];
+
+                                AccessControlContext stack = AccessController.getContext();
+
+                                Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
+
+                                    @Override
+                                    public Class<?> run() {
+                                        try {
+                                            ReflectUtil.checkPackageAccess(respType);
+                                            ClassLoader cl =
+                                                respClass.getClassLoader();
+                                            return Class.forName(respType, true, cl);
+                                        } catch (Exception e) {
+                                            caughException[0] = e;
+                                        }
+                                        return null;
+                                    }
+                                }, stack, acc);
+
+                                if (caughException[0] != null) {
+                                    throw caughException[0];
+                                }
+
                                 subtype = c.isInstance(response);
                             } catch (Exception e) {
                                 subtype = false;
@@ -2745,16 +2843,37 @@
         return MBeanServerFactory.getClassLoaderRepository(server);
     }
 
-    private Class<?> loadClass(String className)
+    private Class<?> loadClass(final String className)
         throws ClassNotFoundException {
-        try {
-            return Class.forName(className);
-        } catch (ClassNotFoundException e) {
-            final ClassLoaderRepository clr =
-                getClassLoaderRepository();
-            if (clr == null) throw new ClassNotFoundException(className);
-            return clr.loadClass(className);
+        AccessControlContext stack = AccessController.getContext();
+        final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
+
+        Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
+
+            @Override
+            public Class<?> run() {
+                try {
+                    ReflectUtil.checkPackageAccess(className);
+                    return Class.forName(className);
+                } catch (ClassNotFoundException e) {
+                    final ClassLoaderRepository clr =
+                        getClassLoaderRepository();
+                    try {
+                        if (clr == null) throw new ClassNotFoundException(className);
+                        return clr.loadClass(className);
+                    } catch (ClassNotFoundException ex) {
+                        caughtException[0] = ex;
+                    }
+                }
+                return null;
+            }
+        }, stack, acc);
+
+        if (caughtException[0] != null) {
+            throw caughtException[0];
         }
+
+        return c;
     }
 
 
--- a/src/share/classes/javax/swing/JTable.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/javax/swing/JTable.java	Mon Feb 25 08:44:00 2013 +0100
@@ -781,15 +781,11 @@
                         scrollPane.getCorner(JScrollPane.UPPER_TRAILING_CORNER);
                 if (corner == null || corner instanceof UIResource){
                     corner = null;
-                    Object componentClass = UIManager.get(
-                            "Table.scrollPaneCornerComponent");
-                    if (componentClass instanceof Class){
-                        try {
-                            corner = (Component)
-                                    ((Class)componentClass).newInstance();
-                        } catch (Exception e) {
-                            // just ignore and don't set corner
-                        }
+                    try {
+                        corner = (Component) UIManager.get(
+                                "Table.scrollPaneCornerComponent");
+                    } catch (Exception e) {
+                        // just ignore and don't set corner
                     }
                     scrollPane.setCorner(JScrollPane.UPPER_TRAILING_CORNER,
                             corner);
--- a/src/share/classes/javax/swing/RepaintManager.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/javax/swing/RepaintManager.java	Mon Feb 25 08:44:00 2013 +0100
@@ -27,11 +27,12 @@
 
 import java.awt.*;
 import java.awt.event.*;
-import java.awt.peer.ComponentPeer;
-import java.awt.peer.ContainerPeer;
 import java.awt.image.VolatileImage;
+import java.security.AccessControlContext;
 import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.applet.*;
 
 import sun.awt.AWTAccessor;
@@ -39,6 +40,8 @@
 import sun.awt.DisplayChangedListener;
 import sun.awt.SunToolkit;
 import sun.java2d.SunGraphicsEnvironment;
+import sun.misc.JavaSecurityAccess;
+import sun.misc.SharedSecrets;
 import sun.security.action.GetPropertyAction;
 
 import com.sun.java.swing.SwingUtilities3;
@@ -176,6 +179,9 @@
      */
     private final ProcessingRunnable processingRunnable;
 
+    private final static JavaSecurityAccess javaSecurityAccess =
+        SharedSecrets.getJavaSecurityAccess();
+
 
     static {
         volatileImageBufferEnabled = "true".equals(AccessController.
@@ -548,13 +554,26 @@
     // This is called from the toolkit thread when awt needs to run a
     // Runnable before we paint.
     //
-    void nativeQueueSurfaceDataRunnable(AppContext appContext, Component c,
-                                        Runnable r) {
+    void nativeQueueSurfaceDataRunnable(AppContext appContext,
+                                        final Component c, final Runnable r)
+    {
         synchronized(this) {
             if (runnableList == null) {
                 runnableList = new LinkedList<Runnable>();
             }
-            runnableList.add(r);
+            runnableList.add(new Runnable() {
+                public void run() {
+                    AccessControlContext stack = AccessController.getContext();
+                    AccessControlContext acc =
+                        AWTAccessor.getComponentAccessor().getAccessControlContext(c);
+                    javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
+                        public Void run() {
+                            r.run();
+                            return null;
+                        }
+                    }, stack, acc);
+                }
+            });
         }
         scheduleProcessingRunnable(appContext);
     }
@@ -652,9 +671,9 @@
      * @see #addInvalidComponent
      */
     public void validateInvalidComponents() {
-        java.util.List<Component> ic;
+        final java.util.List<Component> ic;
         synchronized(this) {
-            if(invalidComponents == null) {
+            if (invalidComponents == null) {
                 return;
             }
             ic = invalidComponents;
@@ -662,7 +681,17 @@
         }
         int n = ic.size();
         for(int i = 0; i < n; i++) {
-            ic.get(i).validate();
+            final Component c = ic.get(i);
+            AccessControlContext stack = AccessController.getContext();
+            AccessControlContext acc =
+                AWTAccessor.getComponentAccessor().getAccessControlContext(c);
+            javaSecurityAccess.doIntersectionPrivilege(
+                new PrivilegedAction<Void>() {
+                    public Void run() {
+                        c.validate();
+                        return null;
+                    }
+                }, stack, acc);
         }
     }
 
@@ -740,78 +769,78 @@
         paintDirtyRegions(tmpDirtyComponents);
     }
 
-    private void paintDirtyRegions(Map<Component,Rectangle>
-                                   tmpDirtyComponents){
-        int i, count;
-        java.util.List<Component> roots;
-        Component dirtyComponent;
-
-        count = tmpDirtyComponents.size();
-        if (count == 0) {
+    private void paintDirtyRegions(
+        final Map<Component,Rectangle> tmpDirtyComponents)
+    {
+        if (tmpDirtyComponents.isEmpty()) {
             return;
         }
 
-        Rectangle rect;
-        int localBoundsX = 0;
-        int localBoundsY = 0;
-        int localBoundsH;
-        int localBoundsW;
-
-        roots = new ArrayList<Component>(count);
-
+        final java.util.List<Component> roots =
+            new ArrayList<Component>(tmpDirtyComponents.size());
         for (Component dirty : tmpDirtyComponents.keySet()) {
             collectDirtyComponents(tmpDirtyComponents, dirty, roots);
         }
 
-        count = roots.size();
+        final AtomicInteger count = new AtomicInteger(roots.size());
         painting = true;
         try {
-            for(i=0 ; i < count ; i++) {
-                dirtyComponent = roots.get(i);
-                rect = tmpDirtyComponents.get(dirtyComponent);
-                // Sometimes when RepaintManager is changed during the painting
-                // we may get null here, see #6995769 for details
-                if (rect == null) {
-                    continue;
-                }
-                localBoundsH = dirtyComponent.getHeight();
-                localBoundsW = dirtyComponent.getWidth();
+            for (int j=0 ; j < count.get(); j++) {
+                final int i = j;
+                final Component dirtyComponent = roots.get(j);
+                AccessControlContext stack = AccessController.getContext();
+                AccessControlContext acc =
+                    AWTAccessor.getComponentAccessor().getAccessControlContext(dirtyComponent);
+                javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
+                    public Void run() {
+                        Rectangle rect = tmpDirtyComponents.get(dirtyComponent);
+                        // Sometimes when RepaintManager is changed during the painting
+                        // we may get null here, see #6995769 for details
+                        if (rect == null) {
+                            return null;
+                        }
 
-                SwingUtilities.computeIntersection(localBoundsX,
-                                                   localBoundsY,
-                                                   localBoundsW,
-                                                   localBoundsH,
-                                                   rect);
-                if (dirtyComponent instanceof JComponent) {
-                    ((JComponent)dirtyComponent).paintImmediately(
-                        rect.x,rect.y,rect.width, rect.height);
-                }
-                else if (dirtyComponent.isShowing()) {
-                    Graphics g = JComponent.safelyGetGraphics(
-                            dirtyComponent, dirtyComponent);
-                    // If the Graphics goes away, it means someone disposed of
-                    // the window, don't do anything.
-                    if (g != null) {
-                        g.setClip(rect.x, rect.y, rect.width, rect.height);
-                        try {
-                            dirtyComponent.paint(g);
-                        } finally {
-                            g.dispose();
+                        int localBoundsH = dirtyComponent.getHeight();
+                        int localBoundsW = dirtyComponent.getWidth();
+                        SwingUtilities.computeIntersection(0,
+                                                           0,
+                                                           localBoundsW,
+                                                           localBoundsH,
+                                                           rect);
+                        if (dirtyComponent instanceof JComponent) {
+                            ((JComponent)dirtyComponent).paintImmediately(
+                                rect.x,rect.y,rect.width, rect.height);
                         }
+                        else if (dirtyComponent.isShowing()) {
+                            Graphics g = JComponent.safelyGetGraphics(
+                                    dirtyComponent, dirtyComponent);
+                            // If the Graphics goes away, it means someone disposed of
+                            // the window, don't do anything.
+                            if (g != null) {
+                                g.setClip(rect.x, rect.y, rect.width, rect.height);
+                                try {
+                                    dirtyComponent.paint(g);
+                                } finally {
+                                    g.dispose();
+                                }
+                            }
+                        }
+                        // If the repaintRoot has been set, service it now and
+                        // remove any components that are children of repaintRoot.
+                        if (repaintRoot != null) {
+                            adjustRoots(repaintRoot, roots, i + 1);
+                            count.set(roots.size());
+                            paintManager.isRepaintingRoot = true;
+                            repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
+                                                         repaintRoot.getHeight());
+                            paintManager.isRepaintingRoot = false;
+                            // Only service repaintRoot once.
+                            repaintRoot = null;
+                        }
+
+                        return null;
                     }
-                }
-                // If the repaintRoot has been set, service it now and
-                // remove any components that are children of repaintRoot.
-                if (repaintRoot != null) {
-                    adjustRoots(repaintRoot, roots, i + 1);
-                    count = roots.size();
-                    paintManager.isRepaintingRoot = true;
-                    repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
-                                                 repaintRoot.getHeight());
-                    paintManager.isRepaintingRoot = false;
-                    // Only service repaintRoot once.
-                    repaintRoot = null;
-                }
+                }, stack, acc);
             }
         } finally {
             painting = false;
--- a/src/share/classes/javax/swing/UIDefaults.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/javax/swing/UIDefaults.java	Mon Feb 25 08:44:00 2013 +0100
@@ -677,6 +677,8 @@
         try {
             String className = (String)get(uiClassID);
             if (className != null) {
+                ReflectUtil.checkPackageAccess(className);
+
                 Class cls = (Class)get(className);
                 if (cls == null) {
                     if (uiClassLoader == null) {
--- a/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/javax/swing/plaf/nimbus/NimbusLookAndFeel.java	Mon Feb 25 08:44:00 2013 +0100
@@ -159,7 +159,12 @@
 
             // Store Table ScrollPane Corner Component
             uiDefaults.put("Table.scrollPaneCornerComponent",
-                    TableScrollPaneCorner.class);
+                    new UIDefaults.ActiveValue() {
+                        @Override
+                        public Object createValue(UIDefaults table) {
+                            return new TableScrollPaneCorner();
+                        }
+                    });
 
             // Setup the settings for ToolBarSeparator which is custom
             // installed for Nimbus
--- a/src/share/classes/sun/applet/AppletPanel.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/applet/AppletPanel.java	Mon Feb 25 08:44:00 2013 +0100
@@ -45,6 +45,7 @@
 import java.util.Collections;
 import java.util.Locale;
 import java.util.WeakHashMap;
+import sun.awt.AWTAccessor;
 import sun.awt.AppContext;
 import sun.awt.EmbeddedFrame;
 import sun.awt.SunToolkit;
@@ -448,12 +449,12 @@
                       // to avoid deadlock.
                       try {
                           final AppletPanel p = this;
-
-                          EventQueue.invokeAndWait(new Runnable() {
-                                  public void run() {
-                                      p.validate();
-                                  }
-                              });
+                          Runnable r = new Runnable() {
+                              public void run() {
+                                  p.validate();
+                              }
+                          };
+                          AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
                       }
                       catch(InterruptedException ie) {
                       }
@@ -478,18 +479,19 @@
                       try {
                           final AppletPanel p = this;
                           final Applet a = applet;
+                          Runnable r = new Runnable() {
+                              public void run() {
+                                  p.validate();
+                                  a.setVisible(true);
 
-                          EventQueue.invokeAndWait(new Runnable() {
-                                  public void run() {
-                                      p.validate();
-                                      a.setVisible(true);
-
-                                      // Fix for BugTraq ID 4041703.
-                                      // Set the default focus for an applet.
-                                      if (hasInitialFocus())
-                                        setDefaultFocus();
+                                  // Fix for BugTraq ID 4041703.
+                                  // Set the default focus for an applet.
+                                  if (hasInitialFocus()) {
+                                      setDefaultFocus();
                                   }
-                              });
+                              }
+                          };
+                          AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
                       }
                       catch(InterruptedException ie) {
                       }
@@ -512,13 +514,12 @@
                     // to avoid deadlock.
                     try {
                         final Applet a = applet;
-
-                        EventQueue.invokeAndWait(new Runnable() {
-                                public void run()
-                                {
-                                    a.setVisible(false);
-                                }
-                            });
+                        Runnable r = new Runnable() {
+                            public void run() {
+                                a.setVisible(false);
+                            }
+                        };
+                        AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
                     }
                     catch(InterruptedException ie) {
                     }
@@ -570,17 +571,14 @@
                     }
                     status = APPLET_DISPOSE;
 
-                    try
-                    {
+                    try {
                         final Applet a = applet;
-
-                        EventQueue.invokeAndWait(new Runnable()
-                        {
-                            public void run()
-                            {
+                        Runnable r = new Runnable() {
+                            public void run() {
                                 remove(a);
                             }
-                        });
+                        };
+                        AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
                     }
                     catch(InterruptedException ie)
                     {
--- a/src/share/classes/sun/awt/AWTAccessor.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/awt/AWTAccessor.java	Mon Feb 25 08:44:00 2013 +0100
@@ -34,6 +34,8 @@
 import java.awt.event.KeyEvent;
 import java.awt.geom.Point2D;
 import java.awt.peer.ComponentPeer;
+
+import java.lang.reflect.InvocationTargetException;
 import java.security.AccessControlContext;
 
 import java.io.File;
@@ -476,6 +478,12 @@
          * appeared.
          */
         void wakeup(EventQueue eventQueue, boolean isShutdown);
+
+        /**
+         * Static in EventQueue
+         */
+        void invokeAndWait(Object source, Runnable r)
+            throws InterruptedException, InvocationTargetException;
     }
 
     /*
--- a/src/share/classes/sun/awt/AppContext.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/awt/AppContext.java	Mon Feb 25 08:44:00 2013 +0100
@@ -327,21 +327,27 @@
             // Before we return the main "system" AppContext, check to
             // see if there's an AWTSecurityManager installed.  If so,
             // allow it to choose the AppContext to return.
-            SecurityManager securityManager = System.getSecurityManager();
-            if ((securityManager != null) &&
-                (securityManager instanceof AWTSecurityManager))
-            {
-                AWTSecurityManager awtSecMgr = (AWTSecurityManager)securityManager;
-                AppContext secAppContext = awtSecMgr.getAppContext();
-                if (secAppContext != null)  {
-                    appContext = secAppContext; // Return what we're told
-                }
+            AppContext secAppContext = getExecutionAppContext();
+            if (secAppContext != null) {
+                appContext = secAppContext; // Return what we're told
             }
         }
 
         return appContext;
     }
 
+    private final static AppContext getExecutionAppContext() {
+        SecurityManager securityManager = System.getSecurityManager();
+        if ((securityManager != null) &&
+            (securityManager instanceof AWTSecurityManager))
+        {
+            AWTSecurityManager awtSecMgr = (AWTSecurityManager) securityManager;
+            AppContext secAppContext = awtSecMgr.getAppContext();
+            return secAppContext; // Return what we're told
+        }
+        return null;
+    }
+
     /**
      * Returns the main ("system") AppContext.
      *
@@ -806,6 +812,21 @@
             public boolean isMainAppContext() {
                 return (numAppContexts.get() == 1);
             }
+            public Object getContext() {
+                return getAppContext();
+            }
+            public Object getExecutionContext() {
+                return getExecutionAppContext();
+            }
+            public Object get(Object context, Object key) {
+                return ((AppContext)context).get(key);
+            }
+            public void put(Object context, Object key, Object value) {
+                ((AppContext)context).put(key, value);
+            }
+            public void remove(Object context, Object key) {
+                ((AppContext)context).remove(key);
+            }
         });
     }
 }
--- a/src/share/classes/sun/awt/image/ByteComponentRaster.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/awt/image/ByteComponentRaster.java	Mon Feb 25 08:44:00 2013 +0100
@@ -198,7 +198,7 @@
         }
         this.bandOffset = this.dataOffsets[0];
 
-        verify(false);
+        verify();
     }
 
     /**
@@ -857,38 +857,68 @@
     }
 
     /**
-     * Verify that the layout parameters are consistent with
-     * the data.  If strictCheck
-     * is false, this method will check for ArrayIndexOutOfBounds conditions.  If
-     * strictCheck is true, this method will check for additional error
-     * conditions such as line wraparound (width of a line greater than
-     * the scanline stride).
-     * @return   String   Error string, if the layout is incompatible with
-     *                    the data.  Otherwise returns null.
+     * Verify that the layout parameters are consistent with the data.
+     *
+     * The method verifies whether scanline stride and pixel stride do not
+     * cause an integer overflow during calculation of a position of the pixel
+     * in data buffer. It also verifies whether the data buffer has enough data
+     *  to correspond the raster layout attributes.
+     *
+     * @throws RasterFormatException if an integer overflow is detected,
+     * or if data buffer has not enough capacity.
      */
-    private void verify (boolean strictCheck) {
-        // Make sure data for Raster is in a legal range
-        for (int i=0; i < dataOffsets.length; i++) {
+    protected final void verify() {
+        for (int i = 0; i < dataOffsets.length; i++) {
             if (dataOffsets[i] < 0) {
-                throw new RasterFormatException("Data offsets for band "+i+
-                                                "("+dataOffsets[i]+
-                                                ") must be >= 0");
+                throw new RasterFormatException("Data offsets for band " + i
+                            + "(" + dataOffsets[i]
+                            + ") must be >= 0");
             }
         }
 
         int maxSize = 0;
         int size;
 
-        for (int i=0; i < numDataElements; i++) {
-            size = (height-1)*scanlineStride + (width-1)*pixelStride +
-                dataOffsets[i];
+        // we can be sure that width and height are greater than 0
+        if (scanlineStride < 0 ||
+            scanlineStride > (Integer.MAX_VALUE / height))
+        {
+            // integer overflow
+            throw new RasterFormatException("Incorrect scanline stride: "
+                    + scanlineStride);
+        }
+        int lastScanOffset = (height - 1) * scanlineStride;
+
+        if (pixelStride < 0 ||
+            pixelStride > (Integer.MAX_VALUE / width))
+        {
+            // integer overflow
+            throw new RasterFormatException("Incorrect pixel stride: "
+                    + pixelStride);
+        }
+        int lastPixelOffset = (width - 1) * pixelStride;
+
+        if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) {
+            // integer overflow
+            throw new RasterFormatException("Incorrect raster attributes");
+        }
+        lastPixelOffset += lastScanOffset;
+
+        for (int i = 0; i < numDataElements; i++) {
+            size = lastPixelOffset + dataOffsets[i];
+            if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
+                throw new RasterFormatException("Incorrect band offset: "
+                            + dataOffsets[i]);
+
+            }
+
             if (size > maxSize) {
                 maxSize = size;
             }
         }
         if (data.length < maxSize) {
-            throw new RasterFormatException("Data array too small (should be "+
-                                          maxSize+" )");
+            throw new RasterFormatException("Data array too small (should be "
+                    + maxSize + " )");
         }
     }
 
--- a/src/share/classes/sun/awt/image/ByteInterleavedRaster.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/awt/image/ByteInterleavedRaster.java	Mon Feb 25 08:44:00 2013 +0100
@@ -250,7 +250,7 @@
             }
         }
 
-        verify(false);
+        verify();
     }
 
     /**
@@ -1292,33 +1292,6 @@
         return createCompatibleWritableRaster(width,height);
     }
 
-    /**
-     * Verify that the layout parameters are consistent with
-     * the data.  If strictCheck
-     * is false, this method will check for ArrayIndexOutOfBounds conditions.  If
-     * strictCheck is true, this method will check for additional error
-     * conditions such as line wraparound (width of a line greater than
-     * the scanline stride).
-     * @return   String   Error string, if the layout is incompatible with
-     *                    the data.  Otherwise returns null.
-     */
-    private void verify (boolean strictCheck) {
-        int maxSize = 0;
-        int size;
-
-        for (int i=0; i < numDataElements; i++) {
-            size = (height-1)*scanlineStride + (width-1)*pixelStride +
-                dataOffsets[i];
-            if (size > maxSize) {
-                maxSize = size;
-            }
-        }
-        if (data.length < maxSize) {
-            throw new RasterFormatException("Data array too small (should be "+
-                                          maxSize+" )");
-        }
-    }
-
     public String toString() {
         return new String ("ByteInterleavedRaster: width = "+width+" height = "
                            + height
--- a/src/share/classes/sun/awt/image/ShortComponentRaster.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/awt/image/ShortComponentRaster.java	Mon Feb 25 08:44:00 2013 +0100
@@ -198,7 +198,7 @@
         }
         this.bandOffset = this.dataOffsets[0];
 
-        verify(false);
+        verify();
     }
 
     /**
@@ -791,38 +791,67 @@
     }
 
     /**
-     * Verify that the layout parameters are consistent with
-     * the data.  If strictCheck
-     * is false, this method will check for ArrayIndexOutOfBounds conditions.  If
-     * strictCheck is true, this method will check for additional error
-     * conditions such as line wraparound (width of a line greater than
-     * the scanline stride).
-     * @return   String   Error string, if the layout is incompatible with
-     *                    the data.  Otherwise returns null.
+     * Verify that the layout parameters are consistent with the data.
+     *
+     * The method verifies whether scanline stride and pixel stride do not
+     * cause an integer overflow during calculation of a position of the pixel
+     * in data buffer. It also verifies whether the data buffer has enough data
+     *  to correspond the raster layout attributes.
+     *
+     * @throws RasterFormatException if an integer overflow is detected,
+     * or if data buffer has not enough capacity.
      */
-    private void verify (boolean strictCheck) {
-        // Make sure data for Raster is in a legal range
-        for (int i=0; i < dataOffsets.length; i++) {
+    protected final void verify() {
+        for (int i = 0; i < dataOffsets.length; i++) {
             if (dataOffsets[i] < 0) {
-                throw new RasterFormatException("Data offsets for band "+i+
-                                                "("+dataOffsets[i]+
-                                                ") must be >= 0");
+                throw new RasterFormatException("Data offsets for band " + i
+                            + "(" + dataOffsets[i]
+                            + ") must be >= 0");
             }
         }
 
         int maxSize = 0;
         int size;
 
-        for (int i=0; i < numDataElements; i++) {
-            size = (height-1)*scanlineStride + (width-1)*pixelStride +
-                dataOffsets[i];
+        // we can be sure that width and height are greater than 0
+        if (scanlineStride < 0 ||
+            scanlineStride > (Integer.MAX_VALUE / height))
+        {
+            // integer overflow
+            throw new RasterFormatException("Incorrect scanline stride: "
+                    + scanlineStride);
+        }
+        int lastScanOffset = (height - 1) * scanlineStride;
+
+        if (pixelStride < 0 ||
+            pixelStride > (Integer.MAX_VALUE / width))
+        {
+            // integer overflow
+            throw new RasterFormatException("Incorrect pixel stride: "
+                    + pixelStride);
+        }
+        int lastPixelOffset = (width - 1) * pixelStride;
+
+        if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) {
+            // integer overflow
+            throw new RasterFormatException("Incorrect raster attributes");
+        }
+        lastPixelOffset += lastScanOffset;
+
+        for (int i = 0; i < numDataElements; i++) {
+            size = lastPixelOffset + dataOffsets[i];
+            if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
+                throw new RasterFormatException("Incorrect band offset: "
+                            + dataOffsets[i]);
+            }
+
             if (size > maxSize) {
                 maxSize = size;
             }
         }
         if (data.length < maxSize) {
-            throw new RasterFormatException("Data array too small (should be "+
-                                          maxSize+" )");
+            throw new RasterFormatException("Data array too small (should be "
+                    + maxSize + " )");
         }
     }
 
--- a/src/share/classes/sun/awt/image/ShortInterleavedRaster.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/awt/image/ShortInterleavedRaster.java	Mon Feb 25 08:44:00 2013 +0100
@@ -171,7 +171,7 @@
               sampleModel);
         }
         this.bandOffset = this.dataOffsets[0];
-        verify(false);
+        verify();
     }
 
     /**
@@ -762,33 +762,6 @@
         return createCompatibleWritableRaster(width,height);
     }
 
-    /**
-     * Verify that the layout parameters are consistent with
-     * the data.  If strictCheck
-     * is false, this method will check for ArrayIndexOutOfBounds conditions.  If
-     * strictCheck is true, this method will check for additional error
-     * conditions such as line wraparound (width of a line greater than
-     * the scanline stride).
-     * @return   String   Error string, if the layout is incompatible with
-     *                    the data.  Otherwise returns null.
-     */
-    private void verify (boolean strictCheck) {
-        int maxSize = 0;
-        int size;
-
-        for (int i=0; i < numDataElements; i++) {
-            size = (height-1)*scanlineStride + (width-1)*pixelStride +
-                dataOffsets[i];
-            if (size > maxSize) {
-                maxSize = size;
-            }
-        }
-        if (data.length < maxSize) {
-            throw new RasterFormatException("Data array too small (should be "+
-                                          maxSize+" )");
-        }
-    }
-
     public String toString() {
         return new String ("ShortInterleavedRaster: width = "+width
                            +" height = " + height
--- a/src/share/classes/sun/misc/JavaAWTAccess.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/misc/JavaAWTAccess.java	Mon Feb 25 08:44:00 2013 +0100
@@ -26,6 +26,14 @@
 package sun.misc;
 
 public interface JavaAWTAccess {
+    public Object getContext();
+    public Object getExecutionContext();
+
+    public Object get(Object context, Object key);
+    public void put(Object context, Object key, Object value);
+    public void remove(Object context, Object key);
+
+    // convenience methods whose context is the object returned by getContext()
     public Object get(Object key);
     public void put(Object key, Object value);
     public void remove(Object key);
--- a/src/share/classes/sun/net/httpserver/ChunkedInputStream.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/net/httpserver/ChunkedInputStream.java	Mon Feb 25 08:44:00 2013 +0100
@@ -41,8 +41,12 @@
 
     private boolean needToReadHeader = true;
 
-    static char CR = '\r';
-    static char LF = '\n';
+    final static char CR = '\r';
+    final static char LF = '\n';
+    /*
+     * Maximum chunk header size of 2KB + 2 bytes for CRLF
+     */
+    private final static int MAX_CHUNK_HEADER_SIZE = 2050;
 
     private int numeric (char[] arr, int nchars) throws IOException {
         assert arr.length >= nchars;
@@ -73,10 +77,14 @@
         char[] len_arr = new char [16];
         int len_size = 0;
         boolean end_of_len = false;
+        int read = 0;
 
         while ((c=in.read())!= -1) {
             char ch = (char) c;
-            if (len_size == len_arr.length -1) {
+            read++;
+            if ((len_size == len_arr.length -1) ||
+                (read > MAX_CHUNK_HEADER_SIZE))
+            {
                 throw new IOException ("invalid chunk header");
             }
             if (gotCR) {
--- a/src/share/classes/sun/net/www/http/ChunkedInputStream.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/net/www/http/ChunkedInputStream.java	Mon Feb 25 08:44:00 2013 +0100
@@ -125,6 +125,11 @@
      */
     private boolean closed;
 
+    /*
+     * Maximum chunk header size of 2KB + 2 bytes for CRLF
+     */
+    private final static int MAX_CHUNK_HEADER_SIZE = 2050;
+
     /**
      * State to indicate that next field should be :-
      *  chunk-size [ chunk-extension ] CRLF
@@ -290,6 +295,10 @@
                             break;
                         }
                         pos++;
+                        if ((pos - rawPos) >= MAX_CHUNK_HEADER_SIZE) {
+                            error = true;
+                            throw new IOException("Chunk header too long");
+                        }
                     }
                     if (pos >= rawCount) {
                         return;
--- a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java	Mon Feb 25 08:44:00 2013 +0100
@@ -421,7 +421,7 @@
 
         synchronized (writeLock) {
             ensureOpen();
-            InetSocketAddress isa = (InetSocketAddress)target;
+            InetSocketAddress isa = Net.checkAddress(target);
             InetAddress ia = isa.getAddress();
             if (ia == null)
                 throw new IOException("Target address not resolved");
@@ -432,9 +432,9 @@
                     SecurityManager sm = System.getSecurityManager();
                     if (sm != null) {
                         if (ia.isMulticastAddress()) {
-                            sm.checkMulticast(isa.getAddress());
+                            sm.checkMulticast(ia);
                         } else {
-                            sm.checkConnect(isa.getAddress().getHostAddress(),
+                            sm.checkConnect(ia.getHostAddress(),
                                             isa.getPort());
                         }
                     }
@@ -454,7 +454,7 @@
                     return 0;
                 writerThread = NativeThread.current();
                 do {
-                    n = send(fd, src, target);
+                    n = send(fd, src, isa);
                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 
                 synchronized (stateLock) {
@@ -471,7 +471,7 @@
         }
     }
 
-    private int send(FileDescriptor fd, ByteBuffer src, SocketAddress target)
+    private int send(FileDescriptor fd, ByteBuffer src, InetSocketAddress target)
         throws IOException
     {
         if (src instanceof DirectBuffer)
@@ -502,7 +502,7 @@
     }
 
     private int sendFromNativeBuffer(FileDescriptor fd, ByteBuffer bb,
-                                            SocketAddress target)
+                                     InetSocketAddress target)
         throws IOException
     {
         int pos = bb.position();
@@ -514,7 +514,7 @@
         int written;
         try {
             written = send0(preferIPv6, fd, ((DirectBuffer)bb).address() + pos,
-                            rem, target);
+                            rem, target.getAddress(), target.getPort());
         } catch (PortUnreachableException pue) {
             if (isConnected())
                 throw pue;
@@ -1116,8 +1116,8 @@
                                 boolean connected)
         throws IOException;
 
-    private native int send0(boolean preferIPv6, FileDescriptor fd, long address, int len,
-                             SocketAddress sa)
+    private native int send0(boolean preferIPv6, FileDescriptor fd, long address,
+                             int len, InetAddress addr, int port)
         throws IOException;
 
     static {
--- a/src/share/classes/sun/reflect/misc/ReflectUtil.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/reflect/misc/ReflectUtil.java	Mon Feb 25 08:44:00 2013 +0100
@@ -178,4 +178,31 @@
 
         return !isAncestor(from, to);
     }
+
+    /**
+     * Access check on the interfaces that a proxy class implements and throw
+     * {@code SecurityException} if it accesses a restricted package.
+     *
+     * @param ccl the caller's class loader
+     * @param interfaces the list of interfaces that a proxy class implements
+     *
+     * @see Proxy#checkProxyAccess
+     */
+    public static void checkProxyPackageAccess(ClassLoader ccl,
+                                               Class<?>... interfaces)
+    {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            for (Class<?> intf : interfaces) {
+                ClassLoader cl = intf.getClassLoader();
+                if (needsPackageAccessCheck(ccl, cl)) {
+                    checkPackageAccess(intf);
+                }
+            }
+        }
+    }
+
+    // Note that bytecode instrumentation tools may exclude 'sun.*'
+    // classes but not generated proxy classes and so keep it in com.sun.*
+    public static final String PROXY_PACKAGE = "com.sun.proxy";
 }
--- a/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java	Mon Feb 25 08:44:00 2013 +0100
@@ -153,7 +153,7 @@
                     returnServerError(e.getMessage());
                 }
             else
-                returnClientError("invalid command: " + command);
+                returnClientError("invalid command.");
         } catch (Exception e) {
             returnServerError("internal error: " + e.getMessage());
         }
@@ -225,7 +225,7 @@
         try {
             port = Integer.parseInt(param);
         } catch (NumberFormatException e) {
-            throw new CGIClientException("invalid port number: " + param);
+            throw new CGIClientException("invalid port number.");
         }
         if (port <= 0 || port > 0xFFFF)
             throw new CGIClientException("invalid port: " + port);
@@ -293,11 +293,14 @@
                     "unexpected EOF reading server response");
 
             if (line.toLowerCase().startsWith(key)) {
-                // if contentLengthFound is true
-                // we should probably do something here
-                responseContentLength =
-                    Integer.parseInt(line.substring(key.length()).trim());
-                contentLengthFound = true;
+                if (contentLengthFound) {
+                    throw new CGIServerException(
+                            "Multiple Content-length entries found.");
+                } else {
+                    responseContentLength =
+                        Integer.parseInt(line.substring(key.length()).trim());
+                    contentLengthFound = true;
+                }
             }
         } while ((line.length() != 0) &&
                  (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
--- a/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java	Mon Feb 25 08:44:00 2013 +0100
@@ -70,11 +70,14 @@
                 throw new EOFException();
 
             if (line.toLowerCase().startsWith(key)) {
-                // if contentLengthFound is true
-                // we should probably do something here
-                bytesLeft =
-                    Integer.parseInt(line.substring(key.length()).trim());
-                contentLengthFound = true;
+                if (contentLengthFound) {
+                    throw new IOException(
+                            "Multiple Content-length entries found.");
+                } else {
+                    bytesLeft =
+                        Integer.parseInt(line.substring(key.length()).trim());
+                    contentLengthFound = true;
+                }
             }
 
             // The idea here is to go past the first blank line.
--- a/src/share/classes/sun/security/pkcs11/P11KeyAgreement.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/pkcs11/P11KeyAgreement.java	Mon Feb 25 08:44:00 2013 +0100
@@ -37,6 +37,7 @@
 import static sun.security.pkcs11.TemplateManager.*;
 import sun.security.pkcs11.wrapper.*;
 import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
+import sun.security.util.KeyUtil;
 
 /**
  * KeyAgreement implementation class. This class currently supports
@@ -134,6 +135,10 @@
         BigInteger p, g, y;
         if (key instanceof DHPublicKey) {
             DHPublicKey dhKey = (DHPublicKey)key;
+
+            // validate the Diffie-Hellman public key
+            KeyUtil.validate(dhKey);
+
             y = dhKey.getY();
             DHParameterSpec params = dhKey.getParams();
             p = params.getP();
@@ -145,6 +150,10 @@
             try {
                 DHPublicKeySpec spec = kf.engineGetKeySpec(
                         key, DHPublicKeySpec.class);
+
+                // validate the Diffie-Hellman public key
+                KeyUtil.validate(spec);
+
                 y = spec.getY();
                 p = spec.getP();
                 g = spec.getG();
--- a/src/share/classes/sun/security/ssl/CipherBox.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/CipherBox.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, 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
@@ -392,7 +392,8 @@
      * uniformly use the bad_record_mac alert to hide the specific type of
      * the error.
      */
-    int decrypt(byte[] buf, int offset, int len) throws BadPaddingException {
+    int decrypt(byte[] buf, int offset, int len,
+            int tagLen) throws BadPaddingException {
         if (cipher == null) {
             return len;
         }
@@ -416,9 +417,10 @@
                         System.out);
                 } catch (IOException e) { }
             }
+
             if (blockSize != 0) {
-                newLen = removePadding(buf, offset, newLen,
-                             blockSize, protocolVersion);
+                newLen = removePadding(
+                    buf, offset, newLen, tagLen, blockSize, protocolVersion);
 
                 if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
                     if (newLen < blockSize) {
@@ -448,7 +450,7 @@
      *
      *  @see decrypt(byte[], int, int)
      */
-    int decrypt(ByteBuffer bb) throws BadPaddingException {
+    int decrypt(ByteBuffer bb, int tagLen) throws BadPaddingException {
 
         int len = bb.remaining();
 
@@ -471,7 +473,6 @@
             }
 
             if (debug != null && Debug.isOn("plaintext")) {
-                bb.position(pos);
                 try {
                     HexDumpEncoder hd = new HexDumpEncoder();
 
@@ -479,7 +480,8 @@
                         "Padded plaintext after DECRYPTION:  len = "
                         + newLen);
 
-                    hd.encodeBuffer(bb, System.out);
+                    hd.encodeBuffer(
+                        (ByteBuffer)bb.duplicate().position(pos), System.out);
                 } catch (IOException e) { }
             }
 
@@ -488,7 +490,8 @@
              */
             if (blockSize != 0) {
                 bb.position(pos);
-                newLen = removePadding(bb, blockSize, protocolVersion);
+                newLen = removePadding(
+                    bb, tagLen, blockSize, protocolVersion);
 
                 if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
                     if (newLen < blockSize) {
@@ -590,6 +593,65 @@
         return newlen;
     }
 
+    /*
+     * A constant-time check of the padding.
+     *
+     * NOTE that we are checking both the padding and the padLen bytes here.
+     *
+     * The caller MUST ensure that the len parameter is a positive number.
+     */
+    private static int[] checkPadding(
+            byte[] buf, int offset, int len, byte pad) {
+
+        if (len <= 0) {
+            throw new RuntimeException("padding len must be positive");
+        }
+
+        // An array of hits is used to prevent Hotspot optimization for
+        // the purpose of a constant-time check.
+        int[] results = {0, 0};    // {missed #, matched #}
+        for (int i = 0; i <= 256;) {
+            for (int j = 0; j < len && i <= 256; j++, i++) {     // j <= i
+                if (buf[offset + j] != pad) {
+                    results[0]++;       // mismatched padding data
+                } else {
+                    results[1]++;       // matched padding data
+                }
+            }
+        }
+
+        return results;
+    }
+
+    /*
+     * A constant-time check of the padding.
+     *
+     * NOTE that we are checking both the padding and the padLen bytes here.
+     *
+     * The caller MUST ensure that the bb parameter has remaining.
+     */
+    private static int[] checkPadding(ByteBuffer bb, byte pad) {
+
+        if (!bb.hasRemaining()) {
+            throw new RuntimeException("hasRemaining() must be positive");
+        }
+
+        // An array of hits is used to prevent Hotspot optimization for
+        // the purpose of a constant-time check.
+        int[] results = {0, 0};    // {missed #, matched #}
+        bb.mark();
+        for (int i = 0; i <= 256; bb.reset()) {
+            for (; bb.hasRemaining() && i <= 256; i++) {
+                if (bb.get() != pad) {
+                    results[0]++;       // mismatched padding data
+                } else {
+                    results[1]++;       // matched padding data
+                }
+            }
+        }
+
+        return results;
+    }
 
     /*
      * Typical TLS padding format for a 64 bit block cipher is as follows:
@@ -602,86 +664,95 @@
      * as it makes the data a multiple of the block size
      */
     private static int removePadding(byte[] buf, int offset, int len,
-            int blockSize, ProtocolVersion protocolVersion)
-            throws BadPaddingException {
+            int tagLen, int blockSize,
+            ProtocolVersion protocolVersion) throws BadPaddingException {
+
         // last byte is length byte (i.e. actual padding length - 1)
         int padOffset = offset + len - 1;
-        int pad = buf[padOffset] & 0x0ff;
+        int padLen = buf[padOffset] & 0xFF;
 
-        int newlen = len - (pad + 1);
-        if (newlen < 0) {
-            throw new BadPaddingException("Padding length invalid: " + pad);
+        int newLen = len - (padLen + 1);
+        if ((newLen - tagLen) < 0) {
+            // If the buffer is not long enough to contain the padding plus
+            // a MAC tag, do a dummy constant-time padding check.
+            //
+            // Note that it is a dummy check, so we won't care about what is
+            // the actual padding data.
+            checkPadding(buf, offset, len, (byte)(padLen & 0xFF));
+
+            throw new BadPaddingException("Invalid Padding length: " + padLen);
         }
 
+        // The padding data should be filled with the padding length value.
+        int[] results = checkPadding(buf, offset + newLen,
+                        padLen + 1, (byte)(padLen & 0xFF));
         if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
-            for (int i = 1; i <= pad; i++) {
-                int val = buf[padOffset - i] & 0xff;
-                if (val != pad) {
-                    throw new BadPaddingException
-                                        ("Invalid TLS padding: " + val);
-                }
+            if (results[0] != 0) {          // padding data has invalid bytes
+                throw new BadPaddingException("Invalid TLS padding data");
             }
         } else { // SSLv3
             // SSLv3 requires 0 <= length byte < block size
             // some implementations do 1 <= length byte <= block size,
             // so accept that as well
             // v3 does not require any particular value for the other bytes
-            if (pad > blockSize) {
-                throw new BadPaddingException("Invalid SSLv3 padding: " + pad);
+            if (padLen > blockSize) {
+                throw new BadPaddingException("Invalid SSLv3 padding");
             }
         }
-        return newlen;
+        return newLen;
     }
 
     /*
      * Position/limit is equal the removed padding.
      */
     private static int removePadding(ByteBuffer bb,
-            int blockSize, ProtocolVersion protocolVersion)
-            throws BadPaddingException {
+            int tagLen, int blockSize,
+            ProtocolVersion protocolVersion) throws BadPaddingException {
 
         int len = bb.remaining();
         int offset = bb.position();
 
         // last byte is length byte (i.e. actual padding length - 1)
         int padOffset = offset + len - 1;
-        int pad = bb.get(padOffset) & 0x0ff;
+        int padLen = bb.get(padOffset) & 0xFF;
 
-        int newlen = len - (pad + 1);
-        if (newlen < 0) {
-            throw new BadPaddingException("Padding length invalid: " + pad);
+        int newLen = len - (padLen + 1);
+        if ((newLen - tagLen) < 0) {
+            // If the buffer is not long enough to contain the padding plus
+            // a MAC tag, do a dummy constant-time padding check.
+            //
+            // Note that it is a dummy check, so we won't care about what is
+            // the actual padding data.
+            checkPadding(bb.duplicate(), (byte)(padLen & 0xFF));
+
+            throw new BadPaddingException("Invalid Padding length: " + padLen);
         }
 
-        /*
-         * We could zero the padding area, but not much useful
-         * information there.
-         */
+        // The padding data should be filled with the padding length value.
+        int[] results = checkPadding(
+                (ByteBuffer)bb.duplicate().position(offset + newLen),
+                (byte)(padLen & 0xFF));
         if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
-            bb.put(padOffset, (byte)0);         // zero the padding.
-            for (int i = 1; i <= pad; i++) {
-                int val = bb.get(padOffset - i) & 0xff;
-                if (val != pad) {
-                    throw new BadPaddingException
-                                        ("Invalid TLS padding: " + val);
-                }
+            if (results[0] != 0) {          // padding data has invalid bytes
+                throw new BadPaddingException("Invalid TLS padding data");
             }
         } else { // SSLv3
             // SSLv3 requires 0 <= length byte < block size
             // some implementations do 1 <= length byte <= block size,
             // so accept that as well
             // v3 does not require any particular value for the other bytes
-            if (pad > blockSize) {
-                throw new BadPaddingException("Invalid SSLv3 padding: " + pad);
+            if (padLen > blockSize) {
+                throw new BadPaddingException("Invalid SSLv3 padding");
             }
         }
 
         /*
          * Reset buffer limit to remove padding.
          */
-        bb.position(offset + newlen);
-        bb.limit(offset + newlen);
+        bb.position(offset + newLen);
+        bb.limit(offset + newLen);
 
-        return newlen;
+        return newLen;
     }
 
     /*
@@ -708,4 +779,45 @@
     boolean isCBCMode() {
         return isCBCMode;
     }
+
+    /**
+     * Is the cipher null?
+     *
+     * @return true if the cipher is null, false otherwise.
+     */
+    boolean isNullCipher() {
+        return cipher == null;
+    }
+
+    /**
+     * Sanity check the length of a fragment before decryption.
+     *
+     * In CBC mode, check that the fragment length is one or multiple times
+     * of the block size of the cipher suite, and is at least one (one is the
+     * smallest size of padding in CBC mode) bigger than the tag size of the
+     * MAC algorithm except the explicit IV size for TLS 1.1 or later.
+     *
+     * In non-CBC mode, check that the fragment length is not less than the
+     * tag size of the MAC algorithm.
+     *
+     * @return true if the length of a fragment matches above requirements
+     */
+    boolean sanityCheck(int tagLen, int fragmentLen) {
+        if (!isCBCMode) {
+            return fragmentLen >= tagLen;
+        }
+
+        if ((fragmentLen % blockSize) == 0) {
+            int minimal = tagLen + 1;
+            minimal = (minimal >= blockSize) ? minimal : blockSize;
+            if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
+                minimal += blockSize;   // plus the size of the explicit IV
+            }
+
+            return (fragmentLen >= minimal);
+        }
+
+        return false;
+    }
+
 }
--- a/src/share/classes/sun/security/ssl/CipherSuite.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/CipherSuite.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, 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
@@ -549,9 +549,18 @@
         // size of the MAC value (and MAC key) in bytes
         final int size;
 
-        MacAlg(String name, int size) {
+        // block size of the underlying hash algorithm
+        final int hashBlockSize;
+
+        // minimal padding size of the underlying hash algorithm
+        final int minimalPaddingSize;
+
+        MacAlg(String name, int size,
+                int hashBlockSize, int minimalPaddingSize) {
             this.name = name;
             this.size = size;
+            this.hashBlockSize = hashBlockSize;
+            this.minimalPaddingSize = minimalPaddingSize;
         }
 
         /**
@@ -596,11 +605,11 @@
                         new BulkCipher(CIPHER_AES,     32, 16, true);
 
     // MACs
-    final static MacAlg M_NULL = new MacAlg("NULL", 0);
-    final static MacAlg M_MD5  = new MacAlg("MD5", 16);
-    final static MacAlg M_SHA  = new MacAlg("SHA", 20);
-    final static MacAlg M_SHA256  = new MacAlg("SHA256", 32);
-    final static MacAlg M_SHA384  = new MacAlg("SHA384", 48);
+    final static MacAlg M_NULL    = new MacAlg("NULL",     0,   0,   0);
+    final static MacAlg M_MD5     = new MacAlg("MD5",     16,  64,   9);
+    final static MacAlg M_SHA     = new MacAlg("SHA",     20,  64,   9);
+    final static MacAlg M_SHA256  = new MacAlg("SHA256",  32,  64,   9);
+    final static MacAlg M_SHA384  = new MacAlg("SHA384",  48, 128,  17);
 
     /**
      * PRFs (PseudoRandom Function) from TLS specifications.
--- a/src/share/classes/sun/security/ssl/ClientHandshaker.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/ClientHandshaker.java	Mon Feb 25 08:44:00 2013 +0100
@@ -129,9 +129,8 @@
      */
     @Override
     void processMessage(byte type, int messageLen) throws IOException {
-        if (state > type
-                && (type != HandshakeMessage.ht_hello_request
-                    && state != HandshakeMessage.ht_client_hello)) {
+        if (state >= type
+                && (type != HandshakeMessage.ht_hello_request)) {
             throw new SSLProtocolException(
                     "Handshake message sequence violation, " + type);
         }
@@ -194,8 +193,12 @@
                 }
                 break;
             case K_DH_ANON:
-                this.serverKeyExchange(new DH_ServerKeyExchange(
+                try {
+                    this.serverKeyExchange(new DH_ServerKeyExchange(
                                                 input, protocolVersion));
+                } catch (GeneralSecurityException e) {
+                    throwSSLException("Server key", e);
+                }
                 break;
             case K_DHE_DSS:
             case K_DHE_RSA:
@@ -921,7 +924,7 @@
         case K_DHE_RSA:
         case K_DHE_DSS:
         case K_DH_ANON:
-            preMasterSecret = dh.getAgreedSecret(serverDH);
+            preMasterSecret = dh.getAgreedSecret(serverDH, true);
             break;
         case K_ECDHE_RSA:
         case K_ECDHE_ECDSA:
--- a/src/share/classes/sun/security/ssl/DHClientKeyExchange.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/DHClientKeyExchange.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -29,7 +29,7 @@
 import java.io.IOException;
 import java.io.PrintStream;
 import java.math.BigInteger;
-
+import javax.net.ssl.SSLHandshakeException;
 
 /*
  * Message used by clients to send their Diffie-Hellman public
@@ -51,7 +51,7 @@
     private byte dh_Yc[];               // 1 to 2^16 -1 bytes
 
     BigInteger getClientPublicKey() {
-        return new BigInteger(1, dh_Yc);
+        return dh_Yc == null ? null : new BigInteger(1, dh_Yc);
     }
 
     /*
@@ -73,7 +73,14 @@
      * but that's what the protocol spec requires.)
      */
     DHClientKeyExchange(HandshakeInStream input) throws IOException {
-        dh_Yc = input.getBytes16();
+        if (input.available() >= 2) {
+            dh_Yc = input.getBytes16();
+        } else {
+            // currently, we don't support cipher suites that requires
+            // implicit public key of client.
+            throw new SSLHandshakeException(
+                    "Unsupported implicit client DiffieHellman public key");
+        }
     }
 
     @Override
@@ -87,7 +94,9 @@
 
     @Override
     void send(HandshakeOutStream s) throws IOException {
-        s.putBytes16(dh_Yc);
+        if (dh_Yc != null && dh_Yc.length != 0) {
+            s.putBytes16(dh_Yc);
+        }
     }
 
     @Override
--- a/src/share/classes/sun/security/ssl/DHCrypt.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/DHCrypt.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, 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
@@ -28,12 +28,15 @@
 
 import java.math.BigInteger;
 import java.security.*;
-
+import java.io.IOException;
+import javax.net.ssl.SSLHandshakeException;
 import javax.crypto.SecretKey;
 import javax.crypto.KeyAgreement;
 import javax.crypto.interfaces.DHPublicKey;
 import javax.crypto.spec.*;
 
+import sun.security.util.KeyUtil;
+
 /**
  * This class implements the Diffie-Hellman key exchange algorithm.
  * D-H means combining your private key with your partners public key to
@@ -54,7 +57,8 @@
  *  . if we are server, call DHCrypt(keyLength,random). This generates
  *    an ephemeral keypair of the request length.
  *  . if we are client, call DHCrypt(modulus, base, random). This
- *    generates an ephemeral keypair using the parameters specified by the server.
+ *    generates an ephemeral keypair using the parameters specified by
+ *    the server.
  *  . send parameters and public value to remote peer
  *  . receive peers ephemeral public key
  *  . call getAgreedSecret() to calculate the shared secret
@@ -83,6 +87,9 @@
     // public component of our key, X = (g ^ x) mod p
     private BigInteger publicValue;             // X (aka y)
 
+    // the times to recove from failure if public key validation
+    private static int MAX_FAILOVER_TIMES = 2;
+
     /**
      * Generate a Diffie-Hellman keypair of the specified size.
      */
@@ -90,9 +97,12 @@
         try {
             KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman");
             kpg.initialize(keyLength, random);
-            KeyPair kp = kpg.generateKeyPair();
-            privateKey = kp.getPrivate();
-            DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
+
+            DHPublicKeySpec spec = generateDHPublicKeySpec(kpg);
+            if (spec == null) {
+                throw new RuntimeException("Could not generate DH keypair");
+            }
+
             publicValue = spec.getY();
             modulus = spec.getP();
             base = spec.getG();
@@ -115,20 +125,25 @@
             KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman");
             DHParameterSpec params = new DHParameterSpec(modulus, base);
             kpg.initialize(params, random);
-            KeyPair kp = kpg.generateKeyPair();
-            privateKey = kp.getPrivate();
-            DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
+
+            DHPublicKeySpec spec = generateDHPublicKeySpec(kpg);
+            if (spec == null) {
+                throw new RuntimeException("Could not generate DH keypair");
+            }
+
             publicValue = spec.getY();
         } catch (GeneralSecurityException e) {
             throw new RuntimeException("Could not generate DH keypair", e);
         }
     }
 
+
     static DHPublicKeySpec getDHPublicKeySpec(PublicKey key) {
         if (key instanceof DHPublicKey) {
             DHPublicKey dhKey = (DHPublicKey)key;
             DHParameterSpec params = dhKey.getParams();
-            return new DHPublicKeySpec(dhKey.getY(), params.getP(), params.getG());
+            return new DHPublicKeySpec(dhKey.getY(),
+                                    params.getP(), params.getG());
         }
         try {
             KeyFactory factory = JsseJce.getKeyFactory("DH");
@@ -166,17 +181,32 @@
      * <P>It is illegal to call this member function if the private key
      * has not been set (or generated).
      *
-     * @param peerPublicKey the peer's public key.
-     * @returns the secret, which is an unsigned big-endian integer
-     *  the same size as the Diffie-Hellman modulus.
+     * @param  peerPublicKey the peer's public key.
+     * @param  keyIsValidated whether the {@code peerPublicKey} has beed
+     *         validated
+     * @return the secret, which is an unsigned big-endian integer
+     *         the same size as the Diffie-Hellman modulus.
      */
-    SecretKey getAgreedSecret(BigInteger peerPublicValue) {
+    SecretKey getAgreedSecret(BigInteger peerPublicValue,
+            boolean keyIsValidated) throws IOException {
         try {
             KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
             DHPublicKeySpec spec =
                         new DHPublicKeySpec(peerPublicValue, modulus, base);
             PublicKey publicKey = kf.generatePublic(spec);
             KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
+
+            // validate the Diffie-Hellman public key
+            if (!keyIsValidated &&
+                    !KeyUtil.isOracleJCEProvider(ka.getProvider().getName())) {
+                try {
+                    KeyUtil.validate(spec);
+                } catch (InvalidKeyException ike) {
+                    // prefer handshake_failure alert to internal_error alert
+                    throw new SSLHandshakeException(ike.getMessage());
+                }
+            }
+
             ka.init(privateKey);
             ka.doPhase(publicKey, true);
             return ka.generateSecret("TlsPremasterSecret");
@@ -185,4 +215,33 @@
         }
     }
 
+    // Generate and validate DHPublicKeySpec
+    private DHPublicKeySpec generateDHPublicKeySpec(KeyPairGenerator kpg)
+            throws GeneralSecurityException {
+
+        boolean doExtraValiadtion =
+                    (!KeyUtil.isOracleJCEProvider(kpg.getProvider().getName()));
+        for (int i = 0; i <= MAX_FAILOVER_TIMES; i++) {
+            KeyPair kp = kpg.generateKeyPair();
+            privateKey = kp.getPrivate();
+            DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
+
+            // validate the Diffie-Hellman public key
+            if (doExtraValiadtion) {
+                try {
+                    KeyUtil.validate(spec);
+                } catch (InvalidKeyException ivke) {
+                    if (i == MAX_FAILOVER_TIMES) {
+                        throw ivke;
+                    }
+                    // otherwise, ignore the exception and try the next one
+                    continue;
+                }
+            }
+
+            return spec;
+        }
+
+        return null;
+    }
 }
--- a/src/share/classes/sun/security/ssl/EngineInputRecord.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/EngineInputRecord.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -178,71 +178,6 @@
     }
 
     /*
-     * Verifies and removes the MAC value.  Returns true if
-     * the MAC checks out OK.
-     *
-     * On entry:
-     *     position = beginning of app/MAC data
-     *     limit = end of MAC data.
-     *
-     * On return:
-     *     position = beginning of app data
-     *     limit = end of app data
-     */
-    boolean checkMAC(MAC signer, ByteBuffer bb) {
-        if (internalData) {
-            return checkMAC(signer);
-        }
-
-        int len = signer.MAClen();
-        if (len == 0) { // no mac
-            return true;
-        }
-
-        /*
-         * Grab the original limit
-         */
-        int lim = bb.limit();
-
-        /*
-         * Delineate the area to apply a MAC on.
-         */
-        int macData = lim - len;
-        bb.limit(macData);
-
-        byte[] mac = signer.compute(contentType(), bb);
-
-        if (len != mac.length) {
-            throw new RuntimeException("Internal MAC error");
-        }
-
-        /*
-         * Delineate the MAC values, position was already set
-         * by doing the compute above.
-         *
-         * We could zero the MAC area, but not much useful information
-         * there anyway.
-         */
-        bb.position(macData);
-        bb.limit(lim);
-
-        try {
-            for (int i = 0; i < len; i++) {
-                if (bb.get() != mac[i]) {  // No BB.equals(byte []); !
-                    return false;
-                }
-            }
-            return true;
-        } finally {
-            /*
-             * Position to the data.
-             */
-            bb.rewind();
-            bb.limit(macData);
-        }
-    }
-
-    /*
      * Pass the data down if it's internally cached, otherwise
      * do it here.
      *
@@ -251,21 +186,164 @@
      * If external data(app), return a new ByteBuffer with data to
      * process.
      */
-    ByteBuffer decrypt(CipherBox box, ByteBuffer bb)
-            throws BadPaddingException {
+    ByteBuffer decrypt(MAC signer,
+            CipherBox box, ByteBuffer bb) throws BadPaddingException {
 
         if (internalData) {
-            decrypt(box);
+            decrypt(signer, box);   // MAC is checked during decryption
             return tmpBB;
         }
 
-        box.decrypt(bb);
-        bb.rewind();
+        BadPaddingException reservedBPE = null;
+        int tagLen = signer.MAClen();
+        int cipheredLength = bb.remaining();
+
+        if (!box.isNullCipher()) {
+            // sanity check length of the ciphertext
+            if (!box.sanityCheck(tagLen, cipheredLength)) {
+                throw new BadPaddingException(
+                    "ciphertext sanity check failed");
+            }
+
+            try {
+                // Note that the CipherBox.decrypt() does not change
+                // the capacity of the buffer.
+                box.decrypt(bb, tagLen);
+            } catch (BadPaddingException bpe) {
+                // RFC 2246 states that decryption_failed should be used
+                // for this purpose. However, that allows certain attacks,
+                // so we just send bad record MAC. We also need to make
+                // sure to always check the MAC to avoid a timing attack
+                // for the same issue. See paper by Vaudenay et al and the
+                // update in RFC 4346/5246.
+                //
+                // Failover to message authentication code checking.
+                reservedBPE = bpe;
+            } finally {
+                bb.rewind();
+            }
+        }
+
+        if (tagLen != 0) {
+            int macOffset = bb.limit() - tagLen;
+
+            // Note that although it is not necessary, we run the same MAC
+            // computation and comparison on the payload for both stream
+            // cipher and CBC block cipher.
+            if (bb.remaining() < tagLen) {
+                // negative data length, something is wrong
+                if (reservedBPE == null) {
+                    reservedBPE = new BadPaddingException("bad record");
+                }
+
+                // set offset of the dummy MAC
+                macOffset = cipheredLength - tagLen;
+                bb.limit(cipheredLength);
+            }
+
+            // Run MAC computation and comparison on the payload.
+            if (checkMacTags(contentType(), bb, signer, false)) {
+                if (reservedBPE == null) {
+                    reservedBPE = new BadPaddingException("bad record MAC");
+                }
+            }
+
+            // Run MAC computation and comparison on the remainder.
+            //
+            // It is only necessary for CBC block cipher.  It is used to get a
+            // constant time of MAC computation and comparison on each record.
+            if (box.isCBCMode()) {
+                int remainingLen = calculateRemainingLen(
+                                        signer, cipheredLength, macOffset);
+
+                // NOTE: here we use the InputRecord.buf because I did not find
+                // an effective way to work on ByteBuffer when its capacity is
+                // less than remainingLen.
+
+                // NOTE: remainingLen may be bigger (less than 1 block of the
+                // hash algorithm of the MAC) than the cipheredLength. However,
+                // We won't need to worry about it because we always use a
+                // maximum buffer for every record.  We need a change here if
+                // we use small buffer size in the future.
+                if (remainingLen > buf.length) {
+                    // unlikely to happen, just a placehold
+                    throw new RuntimeException(
+                        "Internal buffer capacity error");
+                }
+
+                // Won't need to worry about the result on the remainder. And
+                // then we won't need to worry about what's actual data to
+                // check MAC tag on.  We start the check from the header of the
+                // buffer so that we don't need to construct a new byte buffer.
+                checkMacTags(contentType(), buf, 0, remainingLen, signer, true);
+            }
+
+            bb.limit(macOffset);
+        }
+
+        // Is it a failover?
+        if (reservedBPE != null) {
+            throw reservedBPE;
+        }
 
         return bb.slice();
     }
 
     /*
+     * Run MAC computation and comparison
+     *
+     * Please DON'T change the content of the ByteBuffer parameter!
+     */
+    private static boolean checkMacTags(byte contentType, ByteBuffer bb,
+            MAC signer, boolean isSimulated) {
+
+        int tagLen = signer.MAClen();
+        int lim = bb.limit();
+        int macData = lim - tagLen;
+
+        bb.limit(macData);
+        byte[] hash = signer.compute(contentType, bb, isSimulated);
+        if (hash == null || tagLen != hash.length) {
+            // Something is wrong with MAC implementation.
+            throw new RuntimeException("Internal MAC error");
+        }
+
+        bb.position(macData);
+        bb.limit(lim);
+        try {
+            int[] results = compareMacTags(bb, hash);
+            return (results[0] != 0);
+        } finally {
+            bb.rewind();
+            bb.limit(macData);
+        }
+    }
+
+    /*
+     * A constant-time comparison of the MAC tags.
+     *
+     * Please DON'T change the content of the ByteBuffer parameter!
+     */
+    private static int[] compareMacTags(ByteBuffer bb, byte[] tag) {
+
+        // An array of hits is used to prevent Hotspot optimization for
+        // the purpose of a constant-time check.
+        int[] results = {0, 0};     // {missed #, matched #}
+
+        // The caller ensures there are enough bytes available in the buffer.
+        // So we won't need to check the remaining of the buffer.
+        for (int i = 0; i < tag.length; i++) {
+            if (bb.get() != tag[i]) {
+                results[0]++;       // mismatched bytes
+            } else {
+                results[1]++;       // matched bytes
+            }
+        }
+
+        return results;
+    }
+
+    /*
      * Override the actual write below.  We do things this way to be
      * consistent with InputRecord.  InputRecord may try to write out
      * data to the peer, and *then* throw an Exception.  This forces
--- a/src/share/classes/sun/security/ssl/EngineOutputRecord.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/EngineOutputRecord.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -118,7 +118,7 @@
             throws IOException {
 
         if (signer.MAClen() != 0) {
-            byte[] hash = signer.compute(contentType(), bb);
+            byte[] hash = signer.compute(contentType(), bb, false);
 
             /*
              * position was advanced to limit in compute above.
--- a/src/share/classes/sun/security/ssl/HandshakeMessage.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/HandshakeMessage.java	Mon Feb 25 08:44:00 2013 +0100
@@ -41,12 +41,14 @@
 
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
+import javax.crypto.spec.DHPublicKeySpec;
 
 import javax.net.ssl.*;
 
 import sun.security.internal.spec.TlsPrfParameterSpec;
 import sun.security.ssl.CipherSuite.*;
 import static sun.security.ssl.CipherSuite.PRF.*;
+import sun.security.util.KeyUtil;
 
 /**
  * Many data structures are involved in the handshake messages.  These
@@ -712,6 +714,7 @@
         this.protocolVersion = protocolVersion;
         this.preferableSignatureAlgorithm = null;
 
+        // The DH key has been validated in the constructor of DHCrypt.
         setValues(obj);
         signature = null;
     }
@@ -728,6 +731,7 @@
 
         this.protocolVersion = protocolVersion;
 
+        // The DH key has been validated in the constructor of DHCrypt.
         setValues(obj);
 
         Signature sig;
@@ -754,7 +758,8 @@
      * DH_anon key exchange
      */
     DH_ServerKeyExchange(HandshakeInStream input,
-            ProtocolVersion protocolVersion) throws IOException {
+            ProtocolVersion protocolVersion)
+            throws IOException, GeneralSecurityException {
 
         this.protocolVersion = protocolVersion;
         this.preferableSignatureAlgorithm = null;
@@ -762,6 +767,10 @@
         dh_p = input.getBytes16();
         dh_g = input.getBytes16();
         dh_Ys = input.getBytes16();
+        KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
+                                             new BigInteger(1, dh_p),
+                                             new BigInteger(1, dh_g)));
+
         signature = null;
     }
 
@@ -782,6 +791,9 @@
         dh_p = input.getBytes16();
         dh_g = input.getBytes16();
         dh_Ys = input.getBytes16();
+        KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
+                                             new BigInteger(1, dh_p),
+                                             new BigInteger(1, dh_g)));
 
         // read the signature and hash algorithm
         if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
--- a/src/share/classes/sun/security/ssl/InputRecord.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/InputRecord.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, 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
@@ -133,44 +133,174 @@
         return handshakeHash;
     }
 
-    /*
-     * Verify and remove the MAC ... used for all records.
-     */
-    boolean checkMAC(MAC signer) {
-        int len = signer.MAClen();
-        if (len == 0) { // no mac
-            return true;
+    void decrypt(MAC signer, CipherBox box) throws BadPaddingException {
+
+        BadPaddingException reservedBPE = null;
+        int tagLen = signer.MAClen();
+        int cipheredLength = count - headerSize;
+
+        if (!box.isNullCipher()) {
+            // sanity check length of the ciphertext
+            if (!box.sanityCheck(tagLen, cipheredLength)) {
+                throw new BadPaddingException(
+                    "ciphertext sanity check failed");
+            }
+
+            try {
+                // Note that the CipherBox.decrypt() does not change
+                // the capacity of the buffer.
+                count = headerSize +
+                        box.decrypt(buf, headerSize, cipheredLength, tagLen);
+            } catch (BadPaddingException bpe) {
+                // RFC 2246 states that decryption_failed should be used
+                // for this purpose. However, that allows certain attacks,
+                // so we just send bad record MAC. We also need to make
+                // sure to always check the MAC to avoid a timing attack
+                // for the same issue. See paper by Vaudenay et al and the
+                // update in RFC 4346/5246.
+                //
+                // Failover to message authentication code checking.
+                reservedBPE = bpe;
+            }
         }
 
-        int offset = count - len;
+        if (tagLen != 0) {
+            int macOffset = count - tagLen;
+            int contentLen = macOffset - headerSize;
 
-        if (offset < headerSize) {
-            // data length would be negative, something is wrong
-            return false;
+            // Note that although it is not necessary, we run the same MAC
+            // computation and comparison on the payload for both stream
+            // cipher and CBC block cipher.
+            if (contentLen < 0) {
+                // negative data length, something is wrong
+                if (reservedBPE == null) {
+                    reservedBPE = new BadPaddingException("bad record");
+                }
+
+                // set offset of the dummy MAC
+                macOffset = headerSize + cipheredLength - tagLen;
+                contentLen = macOffset - headerSize;
+            }
+
+            count -= tagLen;  // Set the count before any MAC checking
+                              // exception occurs, so that the following
+                              // process can read the actual decrypted
+                              // content (minus the MAC) in the fragment
+                              // if necessary.
+
+            // Run MAC computation and comparison on the payload.
+            if (checkMacTags(contentType(),
+                    buf, headerSize, contentLen, signer, false)) {
+                if (reservedBPE == null) {
+                    reservedBPE = new BadPaddingException("bad record MAC");
+                }
+            }
+
+            // Run MAC computation and comparison on the remainder.
+            //
+            // It is only necessary for CBC block cipher.  It is used to get a
+            // constant time of MAC computation and comparison on each record.
+            if (box.isCBCMode()) {
+                int remainingLen = calculateRemainingLen(
+                                        signer, cipheredLength, contentLen);
+
+                // NOTE: remainingLen may be bigger (less than 1 block of the
+                // hash algorithm of the MAC) than the cipheredLength. However,
+                // We won't need to worry about it because we always use a
+                // maximum buffer for every record.  We need a change here if
+                // we use small buffer size in the future.
+                if (remainingLen > buf.length) {
+                    // unlikely to happen, just a placehold
+                    throw new RuntimeException(
+                        "Internal buffer capacity error");
+                }
+
+                // Won't need to worry about the result on the remainder. And
+                // then we won't need to worry about what's actual data to
+                // check MAC tag on.  We start the check from the header of the
+                // buffer so that we don't need to construct a new byte buffer.
+                checkMacTags(contentType(), buf, 0, remainingLen, signer, true);
+            }
         }
 
-        byte[] mac = signer.compute(contentType(), buf,
-            headerSize, offset - headerSize);
+        // Is it a failover?
+        if (reservedBPE != null) {
+            throw reservedBPE;
+        }
+    }
 
-        if (len != mac.length) {
+    /*
+     * Run MAC computation and comparison
+     *
+     * Please DON'T change the content of the byte buffer parameter!
+     */
+    static boolean checkMacTags(byte contentType, byte[] buffer,
+            int offset, int contentLen, MAC signer, boolean isSimulated) {
+
+        int tagLen = signer.MAClen();
+        byte[] hash = signer.compute(
+                contentType, buffer, offset, contentLen, isSimulated);
+        if (hash == null || tagLen != hash.length) {
+            // Something is wrong with MAC implementation.
             throw new RuntimeException("Internal MAC error");
         }
 
-        for (int i = 0; i < len; i++) {
-            if (buf[offset + i] != mac[i]) {
-                return false;
+        int[] results = compareMacTags(buffer, offset + contentLen, hash);
+        return (results[0] != 0);
+    }
+
+    /*
+     * A constant-time comparison of the MAC tags.
+     *
+     * Please DON'T change the content of the byte buffer parameter!
+     */
+    private static int[] compareMacTags(
+            byte[] buffer, int offset, byte[] tag) {
+
+        // An array of hits is used to prevent Hotspot optimization for
+        // the purpose of a constant-time check.
+        int[] results = {0, 0};    // {missed #, matched #}
+
+        // The caller ensures there are enough bytes available in the buffer.
+        // So we won't need to check the length of the buffer.
+        for (int i = 0; i < tag.length; i++) {
+            if (buffer[offset + i] != tag[i]) {
+                results[0]++;       // mismatched bytes
+            } else {
+                results[1]++;       // matched bytes
             }
         }
-        count -= len;
-        return true;
+
+        return results;
     }
 
-    void decrypt(CipherBox box) throws BadPaddingException {
-        int len = count - headerSize;
-        count = headerSize + box.decrypt(buf, headerSize, len);
+    /*
+     * Calculate the length of a dummy buffer to run MAC computation
+     * and comparison on the remainder.
+     *
+     * The caller MUST ensure that the fullLen is not less than usedLen.
+     */
+    static int calculateRemainingLen(
+            MAC signer, int fullLen, int usedLen) {
+
+        int blockLen = signer.hashBlockLen();
+        int minimalPaddingLen = signer.minimalPaddingLen();
+
+        // (blockLen - minimalPaddingLen) is the maximum message size of
+        // the last block of hash function operation. See FIPS 180-4, or
+        // MD5 specification.
+        fullLen += 13 - (blockLen - minimalPaddingLen);
+        usedLen += 13 - (blockLen - minimalPaddingLen);
+
+        // Note: fullLen is always not less than usedLen, and blockLen
+        // is always bigger than minimalPaddingLen, so we don't worry
+        // about negative values. 0x01 is added to the result to ensure
+        // that the return value is positive.  The extra one byte does
+        // not impact the overall MAC compression function evaluations.
+        return 0x01 + (int)(Math.ceil(fullLen/(1.0d * blockLen)) -
+                Math.ceil(usedLen/(1.0d * blockLen))) * signer.hashBlockLen();
     }
 
-
     /*
      * Well ... hello_request messages are _never_ hashed since we can't
      * know when they'd appear in the sequence.
--- a/src/share/classes/sun/security/ssl/MAC.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/MAC.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, 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
@@ -43,8 +43,8 @@
  * provide integrity protection for SSL messages.  The MAC is actually
  * one of several keyed hashes, as associated with the cipher suite and
  * protocol version.  (SSL v3.0 uses one construct, TLS uses another.)
- *
- * <P>NOTE: MAC computation is the only place in the SSL protocol that the
+ * <P>
+ * NOTE: MAC computation is the only place in the SSL protocol that the
  * sequence number is used.  It's also reset to zero with each change of
  * a cipher spec, so this is the only place this state is needed.
  *
@@ -58,6 +58,9 @@
     // Value of the null MAC is fixed
     private static final byte nullMAC[] = new byte[0];
 
+    // internal identifier for the MAC algorithm
+    private final MacAlg        macAlg;
+
     // stuff defined by the kind of MAC algorithm
     private final int           macSize;
 
@@ -82,6 +85,7 @@
 
     private MAC() {
         macSize = 0;
+        macAlg = M_NULL;
         mac = null;
         block = null;
     }
@@ -91,6 +95,7 @@
      */
     MAC(MacAlg macAlg, ProtocolVersion protocolVersion, SecretKey key)
             throws NoSuchAlgorithmException, InvalidKeyException {
+        this.macAlg = macAlg;
         this.macSize = macAlg.size;
 
         String algorithm;
@@ -128,15 +133,31 @@
     }
 
     /**
+     * Returns the hash function block length of the MAC alorithm.
+     */
+    int hashBlockLen() {
+        return macAlg.hashBlockSize;
+    }
+
+    /**
+     * Returns the hash function minimal padding length of the MAC alorithm.
+     */
+    int minimalPaddingLen() {
+        return macAlg.minimalPaddingSize;
+    }
+
+    /**
      * Computes and returns the MAC for the data in this byte array.
      *
      * @param type record type
      * @param buf compressed record on which the MAC is computed
      * @param offset start of compressed record data
      * @param len the size of the compressed record
+     * @param isSimulated if true, simulate the the MAC computation
      */
-    final byte[] compute(byte type, byte buf[], int offset, int len) {
-        return compute(type, null, buf, offset, len);
+    final byte[] compute(byte type, byte buf[],
+            int offset, int len, boolean isSimulated) {
+        return compute(type, null, buf, offset, len, isSimulated);
     }
 
     /**
@@ -149,9 +170,10 @@
      * @param type record type
      * @param bb a ByteBuffer in which the position and limit
      *          demarcate the data to be MAC'd.
+     * @param isSimulated if true, simulate the the MAC computation
      */
-    final byte[] compute(byte type, ByteBuffer bb) {
-        return compute(type, bb, null, 0, bb.remaining());
+    final byte[] compute(byte type, ByteBuffer bb, boolean isSimulated) {
+        return compute(type, bb, null, 0, bb.remaining(), isSimulated);
     }
 
     /**
@@ -204,18 +226,21 @@
      * or buf/offset/len.
      */
     private byte[] compute(byte type, ByteBuffer bb, byte[] buf,
-            int offset, int len) {
+            int offset, int len, boolean isSimulated) {
 
         if (macSize == 0) {
             return nullMAC;
         }
 
-        block[BLOCK_OFFSET_TYPE] = type;
-        block[block.length - 2]  = (byte)(len >> 8);
-        block[block.length - 1]  = (byte)(len     );
+        // MUST NOT increase the sequence number for a simulated computation.
+        if (!isSimulated) {
+            block[BLOCK_OFFSET_TYPE] = type;
+            block[block.length - 2]  = (byte)(len >> 8);
+            block[block.length - 1]  = (byte)(len     );
 
-        mac.update(block);
-        incrementSequenceNumber();
+            mac.update(block);
+            incrementSequenceNumber();
+        }
 
         // content
         if (bb != null) {
--- a/src/share/classes/sun/security/ssl/OutputRecord.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/OutputRecord.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, 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
@@ -205,7 +205,7 @@
         }
         if (signer.MAClen() != 0) {
             byte[] hash = signer.compute(contentType, buf,
-                    headerSize, count - headerSize);
+                    headerSize, count - headerSize, false);
             write(hash);
         }
     }
--- a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java	Mon Feb 25 08:44:00 2013 +0100
@@ -34,7 +34,7 @@
 import javax.net.ssl.*;
 
 import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
-import sun.security.util.KeyLength;
+import sun.security.util.KeyUtil;
 
 /**
  * This is the client key exchange message (CLIENT --> SERVER) used with
@@ -191,7 +191,7 @@
                         "unable to get the plaintext of the premaster secret");
                 }
 
-                int keySize = KeyLength.getKeySize(secretKey);
+                int keySize = KeyUtil.getKeySize(secretKey);
                 if (keySize > 0 && keySize != 384) {       // 384 = 48 * 8
                     if (debug != null && Debug.isOn("handshake")) {
                         System.out.println(
--- a/src/share/classes/sun/security/ssl/SSLEngineImpl.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/SSLEngineImpl.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, 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
@@ -958,35 +958,15 @@
              * throw a fatal alert if the integrity check fails.
              */
             try {
-                decryptedBB = inputRecord.decrypt(readCipher, readBB);
+                decryptedBB = inputRecord.decrypt(readMAC, readCipher, readBB);
             } catch (BadPaddingException e) {
-                // RFC 2246 states that decryption_failed should be used
-                // for this purpose. However, that allows certain attacks,
-                // so we just send bad record MAC. We also need to make
-                // sure to always check the MAC to avoid a timing attack
-                // for the same issue. See paper by Vaudenay et al.
-                //
-                // rewind the BB if necessary.
-                readBB.rewind();
-
-                inputRecord.checkMAC(readMAC, readBB);
-
-                // use the same alert types as for MAC failure below
                 byte alertType = (inputRecord.contentType() ==
                     Record.ct_handshake) ?
                         Alerts.alert_handshake_failure :
                         Alerts.alert_bad_record_mac;
-                fatal(alertType, "Invalid padding", e);
+                fatal(alertType, e.getMessage(), e);
             }
 
-            if (!inputRecord.checkMAC(readMAC, decryptedBB)) {
-                if (inputRecord.contentType() == Record.ct_handshake) {
-                    fatal(Alerts.alert_handshake_failure,
-                        "bad handshake record MAC");
-                } else {
-                    fatal(Alerts.alert_bad_record_mac, "bad record MAC");
-                }
-            }
 
             // if (!inputRecord.decompress(c))
             //     fatal(Alerts.alert_decompression_failure,
--- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, 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
@@ -986,29 +986,13 @@
              * throw a fatal alert if the integrity check fails.
              */
             try {
-                r.decrypt(readCipher);
+                r.decrypt(readMAC, readCipher);
             } catch (BadPaddingException e) {
-                // RFC 2246 states that decryption_failed should be used
-                // for this purpose. However, that allows certain attacks,
-                // so we just send bad record MAC. We also need to make
-                // sure to always check the MAC to avoid a timing attack
-                // for the same issue. See paper by Vaudenay et al.
-                r.checkMAC(readMAC);
-                // use the same alert types as for MAC failure below
                 byte alertType = (r.contentType() == Record.ct_handshake)
                                         ? Alerts.alert_handshake_failure
                                         : Alerts.alert_bad_record_mac;
-                fatal(alertType, "Invalid padding", e);
+                fatal(alertType, e.getMessage(), e);
             }
-            if (!r.checkMAC(readMAC)) {
-                if (r.contentType() == Record.ct_handshake) {
-                    fatal(Alerts.alert_handshake_failure,
-                        "bad handshake record MAC");
-                } else {
-                    fatal(Alerts.alert_bad_record_mac, "bad record MAC");
-                }
-            }
-
 
             // if (!r.decompress(c))
             //     fatal(Alerts.alert_decompression_failure,
--- a/src/share/classes/sun/security/ssl/ServerHandshaker.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java	Mon Feb 25 08:44:00 2013 +0100
@@ -150,7 +150,7 @@
         // In SSLv3 and TLS, messages follow strictly increasing
         // numerical order _except_ for one annoying special case.
         //
-        if ((state > type)
+        if ((state >= type)
                 && (state != HandshakeMessage.ht_client_key_exchange
                     && type != HandshakeMessage.ht_certificate_verify)) {
             throw new SSLProtocolException(
@@ -250,13 +250,15 @@
         }
 
         //
-        // Move the state machine forward except for that annoying
-        // special case.  This means that clients could send extra
-        // cert verify messages; not a problem so long as all of
-        // them actually check out.
+        // Move state machine forward if the message handling
+        // code didn't already do so
         //
-        if (state < type && type != HandshakeMessage.ht_certificate_verify) {
-            state = type;
+        if (state < type) {
+            if(type == HandshakeMessage.ht_certificate_verify) {
+                state = type + 2;    // an annoying special case
+            } else {
+                state = type;
+            }
         }
     }
 
@@ -1406,7 +1408,7 @@
         if (debug != null && Debug.isOn("handshake")) {
             mesg.print(System.out);
         }
-        return dh.getAgreedSecret(mesg.getClientPublicKey());
+        return dh.getAgreedSecret(mesg.getClientPublicKey(), false);
     }
 
     private SecretKey clientKeyExchange(ECDHClientKeyExchange mesg)
--- a/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java	Mon Feb 25 08:44:00 2013 +0100
@@ -38,7 +38,7 @@
 import java.util.Collections;
 import java.util.ArrayList;
 
-import sun.security.util.KeyLength;
+import sun.security.util.KeyUtil;
 
 /**
  * Signature and hash algorithm.
@@ -274,7 +274,7 @@
              * If key size is less than 512, the  digest length should be
              * less than or equal to 20 bytes.
              */
-            int keySize = KeyLength.getKeySize(signingKey);
+            int keySize = KeyUtil.getKeySize(signingKey);
             if (keySize >= 768) {
                 maxDigestLength = HashAlgorithm.SHA512.length;
             } else if ((keySize >= 512) && (keySize < 768)) {
--- a/src/share/classes/sun/security/util/DerIndefLenConverter.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/util/DerIndefLenConverter.java	Mon Feb 25 08:44:00 2013 +0100
@@ -325,6 +325,10 @@
             }
         }
 
+        if (unresolved != 0) {
+            throw new IOException("not all indef len BER resolved");
+        }
+
         newData = new byte[dataSize + numOfTotalLenBytes + unused];
         dataPos=0; newDataPos=0; index=0;
 
--- a/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java	Mon Feb 25 08:44:00 2013 +0100
@@ -440,7 +440,7 @@
 
         // Does this key constraint disable the specified key?
         public boolean disables(Key key) {
-            int size = KeyLength.getKeySize(key);
+            int size = KeyUtil.getKeySize(key);
 
             if (size == 0) {
                 return true;    // we don't allow any key of size 0.
--- a/src/share/classes/sun/security/util/KeyLength.java	Sat Feb 23 13:32:32 2013 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.security.util;
-
-import java.security.Key;
-import java.security.PrivilegedAction;
-import java.security.AccessController;
-import java.security.interfaces.ECKey;
-import java.security.interfaces.RSAKey;
-import java.security.interfaces.DSAKey;
-import javax.crypto.SecretKey;
-import javax.crypto.interfaces.DHKey;
-
-/**
- * A utility class to get key length
- */
-public final class KeyLength {
-
-    /**
-     * Returns the key size of the given key object in bits.
-     *
-     * @param key the key object, cannot be null
-     * @return the key size of the given key object in bits, or -1 if the
-     *       key size is not accessible
-     */
-    final public static int getKeySize(Key key) {
-        int size = -1;
-
-        if (key instanceof Length) {
-            try {
-                Length ruler = (Length)key;
-                size = ruler.length();
-            } catch (UnsupportedOperationException usoe) {
-                // ignore the exception
-            }
-
-            if (size >= 0) {
-                return size;
-            }
-        }
-
-        // try to parse the length from key specification
-        if (key instanceof SecretKey) {
-            SecretKey sk = (SecretKey)key;
-            String format = sk.getFormat();
-            if ("RAW".equals(format) && sk.getEncoded() != null) {
-                size = (sk.getEncoded().length * 8);
-            }   // Otherwise, it may be a unextractable key of PKCS#11, or
-                // a key we are not able to handle.
-        } else if (key instanceof RSAKey) {
-            RSAKey pubk = (RSAKey)key;
-            size = pubk.getModulus().bitLength();
-        } else if (key instanceof ECKey) {
-            ECKey pubk = (ECKey)key;
-            size = pubk.getParams().getOrder().bitLength();
-        } else if (key instanceof DSAKey) {
-            DSAKey pubk = (DSAKey)key;
-            size = pubk.getParams().getP().bitLength();
-        } else if (key instanceof DHKey) {
-            DHKey pubk = (DHKey)key;
-            size = pubk.getParams().getP().bitLength();
-        }   // Otherwise, it may be a unextractable key of PKCS#11, or
-            // a key we are not able to handle.
-
-        return size;
-    }
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/security/util/KeyUtil.java	Mon Feb 25 08:44:00 2013 +0100
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.security.Key;
+import java.security.PrivilegedAction;
+import java.security.AccessController;
+import java.security.InvalidKeyException;
+import java.security.interfaces.ECKey;
+import java.security.interfaces.RSAKey;
+import java.security.interfaces.DSAKey;
+import java.security.spec.KeySpec;
+import javax.crypto.SecretKey;
+import javax.crypto.interfaces.DHKey;
+import javax.crypto.interfaces.DHPublicKey;
+import javax.crypto.spec.DHParameterSpec;
+import javax.crypto.spec.DHPublicKeySpec;
+import java.math.BigInteger;
+
+/**
+ * A utility class to get key length, valiate keys, etc.
+ */
+public final class KeyUtil {
+
+    /**
+     * Returns the key size of the given key object in bits.
+     *
+     * @param key the key object, cannot be null
+     * @return the key size of the given key object in bits, or -1 if the
+     *       key size is not accessible
+     */
+    public static final int getKeySize(Key key) {
+        int size = -1;
+
+        if (key instanceof Length) {
+            try {
+                Length ruler = (Length)key;
+                size = ruler.length();
+            } catch (UnsupportedOperationException usoe) {
+                // ignore the exception
+            }
+
+            if (size >= 0) {
+                return size;
+            }
+        }
+
+        // try to parse the length from key specification
+        if (key instanceof SecretKey) {
+            SecretKey sk = (SecretKey)key;
+            String format = sk.getFormat();
+            if ("RAW".equals(format) && sk.getEncoded() != null) {
+                size = (sk.getEncoded().length * 8);
+            }   // Otherwise, it may be a unextractable key of PKCS#11, or
+                // a key we are not able to handle.
+        } else if (key instanceof RSAKey) {
+            RSAKey pubk = (RSAKey)key;
+            size = pubk.getModulus().bitLength();
+        } else if (key instanceof ECKey) {
+            ECKey pubk = (ECKey)key;
+            size = pubk.getParams().getOrder().bitLength();
+        } else if (key instanceof DSAKey) {
+            DSAKey pubk = (DSAKey)key;
+            size = pubk.getParams().getP().bitLength();
+        } else if (key instanceof DHKey) {
+            DHKey pubk = (DHKey)key;
+            size = pubk.getParams().getP().bitLength();
+        }   // Otherwise, it may be a unextractable key of PKCS#11, or
+            // a key we are not able to handle.
+
+        return size;
+    }
+
+    /**
+     * Returns whether the key is valid or not.
+     * <P>
+     * Note that this method is only apply to DHPublicKey at present.
+     *
+     * @param  publicKey
+     *         the key object, cannot be null
+     *
+     * @throws NullPointerException if {@code publicKey} is null
+     * @throws InvalidKeyException if {@code publicKey} is invalid
+     */
+    public static final void validate(Key key)
+            throws InvalidKeyException {
+        if (key == null) {
+            throw new NullPointerException(
+                "The key to be validated cannot be null");
+        }
+
+        if (key instanceof DHPublicKey) {
+            validateDHPublicKey((DHPublicKey)key);
+        }
+    }
+
+
+    /**
+     * Returns whether the key spec is valid or not.
+     * <P>
+     * Note that this method is only apply to DHPublicKeySpec at present.
+     *
+     * @param  keySpec
+     *         the key spec object, cannot be null
+     *
+     * @throws NullPointerException if {@code keySpec} is null
+     * @throws InvalidKeyException if {@code keySpec} is invalid
+     */
+    public static final void validate(KeySpec keySpec)
+            throws InvalidKeyException {
+        if (keySpec == null) {
+            throw new NullPointerException(
+                "The key spec to be validated cannot be null");
+        }
+
+        if (keySpec instanceof DHPublicKeySpec) {
+            validateDHPublicKey((DHPublicKeySpec)keySpec);
+        }
+    }
+
+    /**
+     * Returns whether the specified provider is Oracle provider or not.
+     * <P>
+     * Note that this method is only apply to SunJCE and SunPKCS11 at present.
+     *
+     * @param  providerName
+     *         the provider name
+     * @return true if, and only if, the provider of the specified
+     *         {@code providerName} is Oracle provider
+     */
+    public static final boolean isOracleJCEProvider(String providerName) {
+        return providerName != null && (providerName.equals("SunJCE") ||
+                                        providerName.startsWith("SunPKCS11"));
+    }
+
+    /**
+     * Returns whether the Diffie-Hellman public key is valid or not.
+     *
+     * Per RFC 2631 and NIST SP800-56A, the following algorithm is used to
+     * validate Diffie-Hellman public keys:
+     * 1. Verify that y lies within the interval [2,p-1]. If it does not,
+     *    the key is invalid.
+     * 2. Compute y^q mod p. If the result == 1, the key is valid.
+     *    Otherwise the key is invalid.
+     */
+    private static void validateDHPublicKey(DHPublicKey publicKey)
+            throws InvalidKeyException {
+        DHParameterSpec paramSpec = publicKey.getParams();
+
+        BigInteger p = paramSpec.getP();
+        BigInteger g = paramSpec.getG();
+        BigInteger y = publicKey.getY();
+
+        validateDHPublicKey(p, g, y);
+    }
+
+    private static void validateDHPublicKey(DHPublicKeySpec publicKeySpec)
+            throws InvalidKeyException {
+        validateDHPublicKey(publicKeySpec.getP(),
+            publicKeySpec.getG(), publicKeySpec.getY());
+    }
+
+    private static void validateDHPublicKey(BigInteger p,
+            BigInteger g, BigInteger y) throws InvalidKeyException {
+
+        // For better interoperability, the interval is limited to [2, p-2].
+        BigInteger leftOpen = BigInteger.ONE;
+        BigInteger rightOpen = p.subtract(BigInteger.ONE);
+        if (y.compareTo(leftOpen) <= 0) {
+            throw new InvalidKeyException(
+                    "Diffie-Hellman public key is too small");
+        }
+        if (y.compareTo(rightOpen) >= 0) {
+            throw new InvalidKeyException(
+                    "Diffie-Hellman public key is too large");
+        }
+
+        // Don't bother to check against the y^q mod p if safe primes are used.
+    }
+}
+
--- a/src/share/classes/sun/security/util/UntrustedCertificates.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/classes/sun/security/util/UntrustedCertificates.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, 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
@@ -737,5 +737,111 @@
         "B8WfedLHjFW/TMcnXlEWKz4=\n" +
         "-----END CERTIFICATE-----");
 
+        //
+        // Revoked DigiCert code signing certificates used to sign malware
+        //
+
+        // Subject: CN=Buster Paper Comercial Ltda,
+        //          O=Buster Paper Comercial Ltda,
+        //          L=S?o Jos? Dos Campos,
+        //          ST=S?o Paulo,
+        //          C=BR
+        // Issuer:  CN=DigiCert Assured ID Code Signing CA-1,
+        //          OU=www.digicert.com,
+        //          O=DigiCert Inc,
+        //          C=US
+        // Serial:  07:b4:4c:db:ff:fb:78:de:05:f4:26:16:72:a6:73:12
+        add("buster-paper-comercial-ltda-72A67312",
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIGwzCCBaugAwIBAgIQB7RM2//7eN4F9CYWcqZzEjANBgkqhkiG9w0BAQUFADBv\n" +
+        "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" +
+        "d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" +
+        "ZGUgU2lnbmluZyBDQS0xMB4XDTEzMDExNzAwMDAwMFoXDTE0MDEyMjEyMDAwMFow\n" +
+        "gY4xCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMR4wHAYDVQQHDBVT\n" +
+        "w6NvIEpvc8OpIERvcyBDYW1wb3MxJDAiBgNVBAoTG0J1c3RlciBQYXBlciBDb21l\n" +
+        "cmNpYWwgTHRkYTEkMCIGA1UEAxMbQnVzdGVyIFBhcGVyIENvbWVyY2lhbCBMdGRh\n" +
+        "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzO0l6jWIpEfO2oUpVHpL\n" +
+        "HETj5lzivNb0S9jKHgGJax917czh81PnGTxwxFXd6gLJuy/XFHvmiSi8g8jzlymn\n" +
+        "2Ji5zQ3CPaz7nomJokSUDlMVJ2qYWtctw4jrdjuI4qtn+koXXUFkWjkf8h8251I4\n" +
+        "tUs7S49HE2Go5owCYP3byajj7fsFAYR/Xb7TdVtndkZsUB/YgOjHovyACjouaNCi\n" +
+        "mDiRyQ6zLLjZGiyeD65Yiseuhp5b8/BL5h1p7w76QYMYMVQNAdtDKut2R8MBpuWf\n" +
+        "Ny7Eoi0x/gm1p9X5Rcl5aN7K0G4UtTAJKbkuUfXddsyFoM0Nx8uo8SgNQ8Y/X5Jx\n" +
+        "BwIDAQABo4IDOTCCAzUwHwYDVR0jBBgwFoAUe2jOKarAF75JeuHlP9an90WPNTIw\n" +
+        "HQYDVR0OBBYEFFLZ3n5nt/Eer7n1bvtOqMb1qKO5MA4GA1UdDwEB/wQEAwIHgDAT\n" +
+        "BgNVHSUEDDAKBggrBgEFBQcDAzBzBgNVHR8EbDBqMDOgMaAvhi1odHRwOi8vY3Js\n" +
+        "My5kaWdpY2VydC5jb20vYXNzdXJlZC1jcy0yMDExYS5jcmwwM6AxoC+GLWh0dHA6\n" +
+        "Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9hc3N1cmVkLWNzLTIwMTFhLmNybDCCAcQGA1Ud\n" +
+        "IASCAbswggG3MIIBswYJYIZIAYb9bAMBMIIBpDA6BggrBgEFBQcCARYuaHR0cDov\n" +
+        "L3d3dy5kaWdpY2VydC5jb20vc3NsLWNwcy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsG\n" +
+        "AQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABD\n" +
+        "AGUAcgB0AGkAZgBpAGMAYQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABh\n" +
+        "AGMAYwBlAHAAdABhAG4AYwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQBy\n" +
+        "AHQAIABDAFAALwBDAFAAUwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBn\n" +
+        "ACAAUABhAHIAdAB5ACAAQQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABs\n" +
+        "AGkAbQBpAHQAIABsAGkAYQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABp\n" +
+        "AG4AYwBvAHIAcABvAHIAYQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBl\n" +
+        "AGYAZQByAGUAbgBjAGUALjCBggYIKwYBBQUHAQEEdjB0MCQGCCsGAQUFBzABhhho\n" +
+        "dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTAYIKwYBBQUHMAKGQGh0dHA6Ly9jYWNl\n" +
+        "cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENvZGVTaWduaW5nQ0Et\n" +
+        "MS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEAPTTQvpOIikXI\n" +
+        "hTLnNbajaFRR5GhQpTzUNgBfF9VYSlNw/wMjpGsrh5RxaJCip52jbehmTgjMRhft\n" +
+        "jRYyml44PAVsCcR9uEoDpCZYpI1fHI1R+F8jd1C9rqprbSwwOG4xlg4SmvTHYs6e\n" +
+        "gBItQ/1p9XY+Sf4Wv1qOuOFL1qvV/5VyR2zdlOQCmKCeMgxt6a/tHLBDiAA67D44\n" +
+        "/vfdoNJl0CU2It0PO60jdCPFNWIRcxL+OSDqAoePeUC7xQ+JsTEIxuUE8+d6w6fc\n" +
+        "BV2mYb1flh22t46GLjh4gyo7xw3aL6L0L0jzlTT6IcEw6NIbaPbIKj/npQnHobYj\n" +
+        "XMuKLxbh7g==\n" +
+        "-----END CERTIFICATE-----");
+
+        // Subject: CN=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME,
+        //          O=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME,
+        //          L=S?o Paulo,
+        //          ST=S?o Paulo,
+        //          C=BR
+        // Issuer:  CN=DigiCert Assured ID Code Signing CA-1,
+        //          OU=www.digicert.com,
+        //          O=DigiCert Inc,
+        //          C=US
+        // Serial:  0a:38:9b:95:ee:73:6d:d1:3b:c0:ed:74:3f:d7:4d:2f
+        add("buster-assistencia-tecnica-electronica-ltda-3FD74D2F",
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIG4DCCBcigAwIBAgIQCjible5zbdE7wO10P9dNLzANBgkqhkiG9w0BAQUFADBv\n" +
+        "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" +
+        "d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" +
+        "ZGUgU2lnbmluZyBDQS0xMB4XDTEyMTEwOTAwMDAwMFoXDTEzMTExNDEyMDAwMFow\n" +
+        "gasxCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMRMwEQYDVQQHDApT\n" +
+        "w6NvIFBhdWxvMTgwNgYDVQQKEy9CVVNURVIgQVNTSVNURU5DSUEgVEVDTklDQSBF\n" +
+        "TEVUUk9OSUNBIExUREEgLSBNRTE4MDYGA1UEAxMvQlVTVEVSIEFTU0lTVEVOQ0lB\n" +
+        "IFRFQ05JQ0EgRUxFVFJPTklDQSBMVERBIC0gTUUwggEiMA0GCSqGSIb3DQEBAQUA\n" +
+        "A4IBDwAwggEKAoIBAQDAqNeEs5/B2CTXGjTOkUIdu6jV6qulOZwdw4sefHWYj1UR\n" +
+        "4z6zPk9kjpUgbnb402RFq88QtfInwddZ/wXn9OxMtDd/3TnC7HrhNS7ga79ZFL2V\n" +
+        "JnmzKHum2Yvh0q82QEJ9tHBR2X9VdKpUIH08Zs3k6cWWM1H0YX0cxA/HohhesQJW\n" +
+        "kwJ3urOIJiH/HeByDk8a1NS8safcCxk5vxvW4WvCg43iT09LeHY5Aa8abKw8lqVb\n" +
+        "0tD5ZSIjdmdj3TT1U37iAHLLRM2DXbxfdbhouUX1c5U1ZHAMA67HwjKiseOiDaHj\n" +
+        "NUGbC37C+cgbc9VVM/cURD8WvS0Kj6fQv7F2QtJDAgMBAAGjggM5MIIDNTAfBgNV\n" +
+        "HSMEGDAWgBR7aM4pqsAXvkl64eU/1qf3RY81MjAdBgNVHQ4EFgQU88EXKAyDsh30\n" +
+        "o9+Gu9a4xUy+FSMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMD\n" +
+        "MHMGA1UdHwRsMGowM6AxoC+GLWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9hc3N1\n" +
+        "cmVkLWNzLTIwMTFhLmNybDAzoDGgL4YtaHR0cDovL2NybDQuZGlnaWNlcnQuY29t\n" +
+        "L2Fzc3VyZWQtY3MtMjAxMWEuY3JsMIIBxAYDVR0gBIIBuzCCAbcwggGzBglghkgB\n" +
+        "hv1sAwEwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9z\n" +
+        "c2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4A\n" +
+        "eQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQA\n" +
+        "ZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUA\n" +
+        "IABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAA\n" +
+        "YQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcA\n" +
+        "cgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIA\n" +
+        "aQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQA\n" +
+        "ZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMIGC\n" +
+        "BggrBgEFBQcBAQR2MHQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0\n" +
+        "LmNvbTBMBggrBgEFBQcwAoZAaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp\n" +
+        "Z2lDZXJ0QXNzdXJlZElEQ29kZVNpZ25pbmdDQS0xLmNydDAMBgNVHRMBAf8EAjAA\n" +
+        "MA0GCSqGSIb3DQEBBQUAA4IBAQAei1QmiXepje8OIfo/WonD4MIXgpPr2dfRaquQ\n" +
+        "A8q63OpTRSveyqdQDCSPpDRF/nvO1Y30yksZvIH1tNBsW5LBdxAKN3lFdBlqBwtE\n" +
+        "Q3jHc0KVVYRJ0FBaGE/PJHmRajscdAhYIcMPhTga0u0tDK+wOHEq3993dfl6yHjA\n" +
+        "XHU2iW5pnk75ZoE39zALD5eKXT8ZXrET5c3XUFJKWA+XuGmdmyzqo0Au49PanBv9\n" +
+        "UlZnabYfqoMArqMS0tGSX4cGgi9/2E+pHG9BX4sFW+ZDumroOA2pxyMWEKjxePEL\n" +
+        "zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc\n" +
+        "-----END CERTIFICATE-----");
+
     }
 }
--- a/src/share/lib/security/java.security-linux	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/lib/security/java.security-linux	Mon Feb 25 08:44:00 2013 +0100
@@ -145,7 +145,19 @@
 # passed to checkPackageAccess unless the
 # corresponding RuntimePermission ("accessClassInPackage."+package) has
 # been granted.
-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.access=sun.,\
+               com.sun.xml.internal.bind.,\
+               com.sun.xml.internal.org.jvnet.staxex.,\
+               com.sun.xml.internal.ws.,\
+               com.sun.imageio.,\
+               com.sun.istack.internal.,\
+               com.sun.jmx.,\
+               com.sun.proxy.,\
+               com.sun.org.apache.xerces.internal.utils.,\
+               com.sun.org.apache.xalan.internal.utils.,\
+               com.sun.org.glassfish.external.,\
+               com.sun.org.glassfish.gmbal.,\
+	       jdk.internal.
 
 #
 # List of comma-separated packages that start with or equal this string
@@ -157,7 +169,19 @@
 # by default, none of the class loaders supplied with the JDK call
 # checkPackageDefinition.
 #
-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.definition=sun.,\
+                   com.sun.xml.internal.bind.,\
+                   com.sun.xml.internal.org.jvnet.staxex.,\
+                   com.sun.xml.internal.ws.,\
+                   com.sun.imageio.,\
+                   com.sun.istack.internal.,\
+                   com.sun.jmx.,\
+                   com.sun.proxy.,\
+                   com.sun.org.apache.xerces.internal.utils.,\
+                   com.sun.org.apache.xalan.internal.utils.,\
+                   com.sun.org.glassfish.external.,\
+                   com.sun.org.glassfish.gmbal.,\
+		   jdk.internal.
 
 #
 # Determines whether this properties file can be appended to
--- a/src/share/lib/security/java.security-macosx	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/lib/security/java.security-macosx	Mon Feb 25 08:44:00 2013 +0100
@@ -146,7 +146,20 @@
 # passed to checkPackageAccess unless the
 # corresponding RuntimePermission ("accessClassInPackage."+package) has
 # been granted.
-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,apple.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.access=sun.,\
+               com.sun.xml.internal.bind.,\
+               com.sun.xml.internal.org.jvnet.staxex.,\
+               com.sun.xml.internal.ws.,\
+               com.sun.imageio.,\
+               com.sun.istack.internal.,\
+               com.sun.jmx.,\
+               com.sun.proxy.,\
+               com.sun.org.apache.xerces.internal.utils.,\
+               com.sun.org.apache.xalan.internal.utils.,\
+               com.sun.org.glassfish.external.,\
+               com.sun.org.glassfish.gmbal.,\
+	       jdk.internal.,\
+               apple.
 
 #
 # List of comma-separated packages that start with or equal this string
@@ -158,7 +171,20 @@
 # by default, none of the class loaders supplied with the JDK call
 # checkPackageDefinition.
 #
-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,apple.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.definition=sun.,\
+                   com.sun.xml.internal.bind.,\
+                   com.sun.xml.internal.org.jvnet.staxex.,\
+                   com.sun.xml.internal.ws.,\
+                   com.sun.imageio.,\
+                   com.sun.istack.internal.,\
+                   com.sun.jmx.,\
+                   com.sun.proxy.,\
+                   com.sun.org.apache.xerces.internal.utils.,\
+                   com.sun.org.apache.xalan.internal.utils.,\
+                   com.sun.org.glassfish.external.,\
+                   com.sun.org.glassfish.gmbal.,\
+		   jdk.internal.,\
+                   apple.
 
 #
 # Determines whether this properties file can be appended to
--- a/src/share/lib/security/java.security-solaris	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/lib/security/java.security-solaris	Mon Feb 25 08:44:00 2013 +0100
@@ -147,7 +147,19 @@
 # passed to checkPackageAccess unless the
 # corresponding RuntimePermission ("accessClassInPackage."+package) has
 # been granted.
-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.access=sun.,\
+               com.sun.xml.internal.bind.,\
+               com.sun.xml.internal.org.jvnet.staxex.,\
+               com.sun.xml.internal.ws.,\
+               com.sun.imageio.,\
+               com.sun.istack.internal.,\
+               com.sun.jmx.,\
+               com.sun.proxy.,\
+               com.sun.org.apache.xerces.internal.utils.,\
+               com.sun.org.apache.xalan.internal.utils.,\
+               com.sun.org.glassfish.external.,\
+               com.sun.org.glassfish.gmbal.,\
+	       jdk.internal.
 
 #
 # List of comma-separated packages that start with or equal this string
@@ -159,7 +171,19 @@
 # by default, none of the class loaders supplied with the JDK call
 # checkPackageDefinition.
 #
-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.definition=sun.,\
+                   com.sun.xml.internal.bind.,\
+                   com.sun.xml.internal.org.jvnet.staxex.,\
+                   com.sun.xml.internal.ws.,\
+                   com.sun.imageio.,\
+                   com.sun.istack.internal.,\
+                   com.sun.jmx.,\
+                   com.sun.proxy.,\
+                   com.sun.org.apache.xerces.internal.utils.,\
+                   com.sun.org.apache.xalan.internal.utils.,\
+                   com.sun.org.glassfish.external.,\
+                   com.sun.org.glassfish.gmbal.,\
+		   jdk.internal.
 
 #
 # Determines whether this properties file can be appended to
--- a/src/share/lib/security/java.security-windows	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/lib/security/java.security-windows	Mon Feb 25 08:44:00 2013 +0100
@@ -146,7 +146,19 @@
 # passed to checkPackageAccess unless the
 # corresponding RuntimePermission ("accessClassInPackage."+package) has
 # been granted.
-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.access=sun.,\
+               com.sun.xml.internal.bind.,\
+               com.sun.xml.internal.org.jvnet.staxex.,\
+               com.sun.xml.internal.ws.,\
+               com.sun.imageio.,\
+               com.sun.istack.internal.,\
+               com.sun.jmx.,\
+               com.sun.proxy.,\
+               com.sun.org.apache.xerces.internal.utils.,\
+               com.sun.org.apache.xalan.internal.utils.,\
+               com.sun.org.glassfish.external.,\
+               com.sun.org.glassfish.gmbal.,\
+	       jdk.internal.
 
 #
 # List of comma-separated packages that start with or equal this string
@@ -158,7 +170,19 @@
 # by default, none of the class loaders supplied with the JDK call
 # checkPackageDefinition.
 #
-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.
+package.definition=sun.,\
+                   com.sun.xml.internal.bind.,\
+                   com.sun.xml.internal.org.jvnet.staxex.,\
+                   com.sun.xml.internal.ws.,\
+                   com.sun.imageio.,\
+                   com.sun.istack.internal.,\
+                   com.sun.jmx.,\
+                   com.sun.proxy.,\
+                   com.sun.org.apache.xerces.internal.utils.,\
+                   com.sun.org.apache.xalan.internal.utils.,\
+                   com.sun.org.glassfish.external.,\
+                   com.sun.org.glassfish.gmbal.,\
+		   jdk.internal.
 
 #
 # Determines whether this properties file can be appended to
--- a/src/share/native/com/sun/java/util/jar/pack/bands.cpp	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/native/com/sun/java/util/jar/pack/bands.cpp	Mon Feb 25 08:44:00 2013 +0100
@@ -187,6 +187,10 @@
 
 entry* band::getRefCommon(cpindex* ix_, bool nullOKwithCaller) {
   CHECK_0;
+  if (ix_ == NULL) {
+      abort("no index");
+      return NULL;
+  }
   assert(ix_->ixTag == ixTag
          || ((ixTag == CONSTANT_All ||
               ixTag == CONSTANT_LoadableValue ||
--- a/src/share/native/com/sun/java/util/jar/pack/bands.h	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/native/com/sun/java/util/jar/pack/bands.h	Mon Feb 25 08:44:00 2013 +0100
@@ -99,8 +99,8 @@
 
   int    getByte()  { assert(ix == null); return vs[0].getByte(); }
   int    getInt()   { assert(ix == null); return vs[0].getInt(); }
-  entry* getRefN()  { assert(ix != null); return getRefCommon(ix, true); }
-  entry* getRef()   { assert(ix != null); return getRefCommon(ix, false); }
+  entry* getRefN()  { return getRefCommon(ix, true); }
+  entry* getRef()   { return getRefCommon(ix, false); }
   entry* getRefUsing(cpindex* ix2)
                     { assert(ix == null); return getRefCommon(ix2, true); }
   entry* getRefCommon(cpindex* ix, bool nullOK);
--- a/src/share/native/com/sun/java/util/jar/pack/jni.cpp	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/native/com/sun/java/util/jar/pack/jni.cpp	Mon Feb 25 08:44:00 2013 +0100
@@ -50,6 +50,7 @@
 static jmethodID currentInstMID;
 static jmethodID readInputMID;
 static jclass    NIclazz;
+static jmethodID getUnpackerPtrMID;
 
 static char* dbg = null;
 
@@ -60,8 +61,8 @@
 
 static unpacker* get_unpacker(JNIEnv *env, jobject pObj, bool noCreate=false) {
   unpacker* uPtr;
-  uPtr = (unpacker*)jlong2ptr(env->GetLongField(pObj, unpackerPtrFID));
-  //fprintf(stderr, "get_unpacker(%p) uPtr=%p\n", pObj, uPtr);
+  jlong p = env->CallLongMethod(pObj, getUnpackerPtrMID);
+  uPtr = (unpacker*)jlong2ptr(p);
   if (uPtr == null) {
     if (noCreate)  return null;
     uPtr = new unpacker();
@@ -94,11 +95,15 @@
   if (env == null)
     return null;
   jobject pObj = env->CallStaticObjectMethod(NIclazz, currentInstMID);
-  //fprintf(stderr, "get_unpacker() pObj=%p\n", pObj);
-  if (pObj == null)
-    return null;
-  // Got pObj and env; now do it the easy way.
-  return get_unpacker(env, pObj);
+  //fprintf(stderr, "get_unpacker0() pObj=%p\n", pObj);
+  if (pObj != null) {
+    // Got pObj and env; now do it the easy way.
+    return get_unpacker(env, pObj);
+  }
+  // this should really not happen, if it does something is seriously
+  // wrong throw an exception
+  THROW_IOE(ERROR_INTERNAL);
+  return null;
 }
 
 static void free_unpacker(JNIEnv *env, jobject pObj, unpacker* uPtr) {
@@ -127,18 +132,23 @@
 
 JNIEXPORT void JNICALL
 Java_com_sun_java_util_jar_pack_NativeUnpack_initIDs(JNIEnv *env, jclass clazz) {
+#ifndef PRODUCT
   dbg = getenv("DEBUG_ATTACH");
   while( dbg != null) { sleep(10); }
+#endif
   NIclazz = (jclass) env->NewGlobalRef(clazz);
   unpackerPtrFID = env->GetFieldID(clazz, "unpackerPtr", "J");
   currentInstMID = env->GetStaticMethodID(clazz, "currentInstance",
                                           "()Ljava/lang/Object;");
   readInputMID = env->GetMethodID(clazz, "readInputFn",
                                   "(Ljava/nio/ByteBuffer;J)J");
+  getUnpackerPtrMID = env->GetMethodID(clazz, "getUnpackerPtr", "()J");
+
   if (unpackerPtrFID == null ||
       currentInstMID == null ||
       readInputMID == null ||
-      NIclazz == null) {
+      NIclazz == null ||
+      getUnpackerPtrMID == null) {
     THROW_IOE("cannot init class members");
   }
 }
@@ -146,8 +156,13 @@
 JNIEXPORT jlong JNICALL
 Java_com_sun_java_util_jar_pack_NativeUnpack_start(JNIEnv *env, jobject pObj,
                                    jobject pBuf, jlong offset) {
-  unpacker* uPtr = get_unpacker(env, pObj);
-
+  // try to get the unpacker pointer the hard way first, we do this to ensure
+  // valid object pointers and env is intact, if not now is good time to bail.
+  unpacker* uPtr = get_unpacker();
+  //fprintf(stderr, "start(%p) uPtr=%p initializing\n", pObj, uPtr);
+  if (uPtr == null) {
+      return -1;
+  }
   // redirect our io to the default log file or whatever.
   uPtr->redirect_stdio();
 
@@ -163,7 +178,12 @@
     else
       { buf = (char*)buf + (size_t)offset; buflen -= (size_t)offset; }
   }
-
+  // before we start off we make sure there is no other error by the time we
+  // get here
+  if (uPtr->aborting()) {
+    THROW_IOE(uPtr->get_abort_message());
+    return 0;
+  }
   uPtr->start(buf, buflen);
   if (uPtr->aborting()) {
     THROW_IOE(uPtr->get_abort_message());
@@ -230,11 +250,14 @@
 
   // We have fetched all the files.
   // Now swallow up any remaining input.
-  if (uPtr->input_remaining() == 0)
+  if (uPtr->input_remaining() == 0) {
     return null;
-  else
-    return env->NewDirectByteBuffer(uPtr->input_scan(),
-                                    uPtr->input_remaining());
+  } else {
+    bytes remaining_bytes;
+    remaining_bytes.malloc(uPtr->input_remaining());
+    remaining_bytes.copyFrom(uPtr->input_scan(), uPtr->input_remaining());
+    return env->NewDirectByteBuffer(remaining_bytes.ptr, remaining_bytes.len);
+  }
 }
 
 JNIEXPORT jlong JNICALL
--- a/src/share/native/com/sun/java/util/jar/pack/unpack.cpp	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/native/com/sun/java/util/jar/pack/unpack.cpp	Mon Feb 25 08:44:00 2013 +0100
@@ -281,11 +281,13 @@
 }
 
 inline cpindex* cpool::getFieldIndex(entry* classRef) {
+  if (classRef == NULL) { abort("missing class reference"); return NULL; }
   assert(classRef->tagMatches(CONSTANT_Class));
   assert((uint)classRef->inord < (uint)tag_count[CONSTANT_Class]);
   return &member_indexes[classRef->inord*2+0];
 }
 inline cpindex* cpool::getMethodIndex(entry* classRef) {
+  if (classRef == NULL) { abort("missing class reference"); return NULL; }
   assert(classRef->tagMatches(CONSTANT_Class));
   assert((uint)classRef->inord < (uint)tag_count[CONSTANT_Class]);
   return &member_indexes[classRef->inord*2+1];
@@ -1291,6 +1293,7 @@
     entry& e = cpMap[i];
     e.refs = U_NEW(entry*, e.nrefs = 2);
     e.refs[0] = cp_band1.getRef();
+    CHECK;
     e.refs[1] = cp_band2.getRef();
     CHECK;
   }
@@ -1371,6 +1374,7 @@
       entry& e = cpMap[i];
       e.refs = U_NEW(entry*, e.nrefs = 1);
       e.refs[0] = cp_MethodType.getRef();
+      CHECK;
   }
 }
 
@@ -2106,6 +2110,7 @@
     int    attrc   = ADH_BYTE_CONTEXT(header);
     int    idx     = ADH_BYTE_INDEX(header);
     entry* name    = attr_definition_name.getRef();
+    CHECK;
     entry* layout  = attr_definition_layout.getRef();
     CHECK;
     attr_defs[attrc].defineLayout(idx, name, layout->value.b.strval());
@@ -2210,7 +2215,9 @@
     if (ics[i].name == NO_ENTRY_YET) {
       // Long form.
       ics[i].outer = ic_outer_class.getRefN();
+      CHECK;
       ics[i].name  = ic_name.getRefN();
+      CHECK;
     } else {
       // Fill in outer and name based on inner.
       bytes& n = ics[i].inner->value.b;
@@ -2733,6 +2740,7 @@
           e = b.getRefUsing(cp.getKQIndex());
         else
           e = b.getRefN();
+        CHECK;
         switch (b.le_len) {
         case 0: break;
         case 1: putu1ref(e); break;
@@ -3118,7 +3126,7 @@
 
 void unpacker::read_bands() {
   byte* rp0 = rp;
-
+  CHECK;
   read_file_header();
   CHECK;
 
@@ -3880,10 +3888,12 @@
 // packed file and len is the length of the buffer.
 // If null, the callback is used to fill an internal buffer.
 void unpacker::start(void* packptr, size_t len) {
+  CHECK;
   NOT_PRODUCT(debug_u = this);
   if (packptr != null && len != 0) {
     inbytes.set((byte*) packptr, len);
   }
+  CHECK;
   read_bands();
 }
 
@@ -4015,6 +4025,7 @@
     NOT_PRODUCT(bc_superfield.setIndex(null));
     NOT_PRODUCT(bc_supermethod.setIndex(null));
   }
+  CHECK;
 
   for (int curIP = 0; ; curIP++) {
     int curPC = (int)(wpoffset() - codeBase);
@@ -4128,7 +4139,8 @@
         int coding = bc_initref.getInt();
         // Find the nth overloading of <init> in classRef.
         entry*   ref = null;
-        cpindex* ix = (classRef == null)? null: cp.getMethodIndex(classRef);
+        cpindex* ix = cp.getMethodIndex(classRef);
+        CHECK;
         for (int j = 0, which_init = 0; ; j++) {
           ref = (ix == null)? null: ix->get(j);
           if (ref == null)  break;  // oops, bad input
@@ -4405,6 +4417,7 @@
       case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_EnclosingMethod):
         aname = cp.sym[cpool::s_EnclosingMethod];
         putref(class_EnclosingMethod_RC.getRefN());
+        CHECK_0;
         putref(class_EnclosingMethod_RDN.getRefN());
         break;
 
@@ -4423,6 +4436,7 @@
         putu2(count = method_Exceptions_N.getInt());
         for (j = 0; j < count; j++) {
           putref(method_Exceptions_RC.getRefN());
+          CHECK_0;
         }
         break;
 
@@ -4455,16 +4469,18 @@
             // (253)     [(1)(2)(2)]
             // (254)     [(1)(2)(2)(2)]
             putu2(code_StackMapTable_offset.getInt());
+            CHECK_0;
             for (int k = (tag - 251); k > 0; k--) {
               put_stackmap_type();
+              CHECK_0;
             }
           } else {
             // (255)     [(1)NH[(2)]NH[(2)]]
             putu2(code_StackMapTable_offset.getInt());
             putu2(j2 = code_StackMapTable_local_N.getInt());
-            while (j2-- > 0)  put_stackmap_type();
+            while (j2-- > 0) {put_stackmap_type(); CHECK_0;}
             putu2(j2 = code_StackMapTable_stack_N.getInt());
-            while (j2-- > 0)  put_stackmap_type();
+            while (j2-- > 0)  {put_stackmap_type(); CHECK_0;}
           }
         }
         break;
@@ -4488,7 +4504,9 @@
           bii    += code_LocalVariableTable_span_O.getInt();
           putu2(to_bci(bii) - bci);
           putref(code_LocalVariableTable_name_RU.getRefN());
+          CHECK_0;
           putref(code_LocalVariableTable_type_RS.getRefN());
+          CHECK_0;
           putu2(code_LocalVariableTable_slot.getInt());
         }
         break;
@@ -4503,7 +4521,9 @@
           bii    += code_LocalVariableTypeTable_span_O.getInt();
           putu2(to_bci(bii) - bci);
           putref(code_LocalVariableTypeTable_name_RU.getRefN());
+          CHECK_0;
           putref(code_LocalVariableTypeTable_type_RS.getRefN());
+          CHECK_0;
           putu2(code_LocalVariableTypeTable_slot.getInt());
         }
         break;
@@ -4531,7 +4551,7 @@
         break;
       }
     }
-
+    CHECK_0;
     if (aname == null) {
       // Unparse a compressor-defined attribute.
       layout_definition* lo = ad.getLayout(idx);
@@ -4687,7 +4707,9 @@
       flags &= ~ACC_IC_LONG_FORM;  // clear high bit if set to get clean zero
       extra_ic.flags = flags;
       extra_ic.outer = class_InnerClasses_outer_RCN.getRefN();
+      CHECK_0;
       extra_ic.name  = class_InnerClasses_name_RUN.getRefN();
+      CHECK_0;
       // Detect if this is an exact copy of the global tuple.
       if (global_ic != null) {
         if (global_ic->flags != extra_ic.flags ||
@@ -4797,6 +4819,7 @@
   julong indexMask = ad.flagIndexMask();
 
   cur_class = class_this.getRef();
+  CHECK;
   cur_super = class_super.getRef();
   CHECK;
 
@@ -4810,6 +4833,7 @@
   putu2(num = class_interface_count.getInt());
   for (i = 0; i < num; i++) {
     putref(class_interface.getRef());
+    CHECK;
   }
 
   write_members(class_field_count.getInt(),  ATTR_CONTEXT_FIELD);
--- a/src/share/native/sun/awt/image/awt_parseImage.c	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/native/sun/awt/image/awt_parseImage.c	Mon Feb 25 08:44:00 2013 +0100
@@ -114,6 +114,62 @@
     return status;
 }
 
+/* Verifies whether the channel offsets are sane and correspond to the type of
+ * the raster.
+ *
+ * Return value:
+ *     0: Failure: channel offsets are invalid
+ *     1: Success
+ */
+static int checkChannelOffsets(RasterS_t *rasterP, int dataArrayLength) {
+    int i, lastPixelOffset, lastScanOffset;
+    switch (rasterP->rasterType) {
+    case COMPONENT_RASTER_TYPE:
+        if (!SAFE_TO_MULT(rasterP->height, rasterP->scanlineStride)) {
+            return 0;
+        }
+        if (!SAFE_TO_MULT(rasterP->width, rasterP->pixelStride)) {
+            return 0;
+        }
+
+        lastScanOffset = (rasterP->height - 1) * rasterP->scanlineStride;
+        lastPixelOffset = (rasterP->width - 1) * rasterP->pixelStride;
+
+
+        if (!SAFE_TO_ADD(lastPixelOffset, lastScanOffset)) {
+            return 0;
+        }
+
+        lastPixelOffset += lastScanOffset;
+
+        for (i = 0; i < rasterP->numDataElements; i++) {
+            int off = rasterP->chanOffsets[i];
+            int size = lastPixelOffset + off;
+
+            if (off < 0 || !SAFE_TO_ADD(lastPixelOffset, off)) {
+                return 0;
+            }
+
+            if (size < lastPixelOffset || size >= dataArrayLength) {
+                // an overflow, or insufficient buffer capacity
+                return 0;
+            }
+        }
+        return 1;
+    case BANDED_RASTER_TYPE:
+        // NB:caller does not support the banded rasters yet,
+        // so this branch of the code must be re-defined in
+        // order to provide valid criteria for the data offsets
+        // verification, when/if banded rasters will be supported.
+        // At the moment, we prohibit banded rasters as well.
+        return 0;
+    default:
+        // PACKED_RASTER_TYPE: does not support channel offsets
+        // UNKNOWN_RASTER_TYPE: should not be used, likely indicates an error
+        return 0;
+    }
+}
+
 /* Parse the raster.  All of the raster information is returned in the
  * rasterP structure.
  *
@@ -125,7 +181,6 @@
 int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) {
     jobject joffs = NULL;
     /* int status;*/
-    int isDiscrete = TRUE;
 
     if (JNU_IsNull(env, jraster)) {
         JNU_ThrowNullPointerException(env, "null Raster object");
@@ -155,6 +210,9 @@
         return -1;
     }
 
+    // make sure that the raster type is initialized
+    rasterP->rasterType = UNKNOWN_RASTER_TYPE;
+
     if (rasterP->numBands <= 0 ||
         rasterP->numBands > MAX_NUMBANDS)
     {
@@ -165,9 +223,14 @@
         return 0;
     }
 
+    rasterP->sppsm.isUsed = 0;
+
     if ((*env)->IsInstanceOf(env, rasterP->jsampleModel,
        (*env)->FindClass(env,"java/awt/image/SinglePixelPackedSampleModel"))) {
         jobject jmask, joffs, jnbits;
+
+        rasterP->sppsm.isUsed = 1;
+
         rasterP->sppsm.maxBitSize = (*env)->GetIntField(env,
                                                         rasterP->jsampleModel,
                                                         g_SPPSMmaxBitID);
@@ -254,7 +317,6 @@
         }
         rasterP->chanOffsets[0] = (*env)->GetIntField(env, jraster, g_BPRdataBitOffsetID);
         rasterP->dataType = BYTE_DATA_TYPE;
-        isDiscrete = FALSE;
     }
     else {
         rasterP->type = sun_awt_image_IntegerComponentRaster_TYPE_CUSTOM;
@@ -265,7 +327,19 @@
         return 0;
     }
 
-    if (isDiscrete) {
+    // do basic validation of the raster structure
+    if (rasterP->width <= 0 || rasterP->height <= 0 ||
+        rasterP->pixelStride <= 0 || rasterP->scanlineStride <= 0)
+    {
+        // invalid raster
+        return -1;
+    }
+
+    // channel (data) offsets
+    switch (rasterP->rasterType) {
+    case COMPONENT_RASTER_TYPE:
+    case BANDED_RASTER_TYPE: // note that this routine does not support banded rasters at the moment
+        // get channel (data) offsets
         rasterP->chanOffsets = NULL;
         if (SAFE_TO_ALLOC_2(rasterP->numDataElements, sizeof(jint))) {
             rasterP->chanOffsets =
@@ -278,10 +352,21 @@
         }
         (*env)->GetIntArrayRegion(env, joffs, 0, rasterP->numDataElements,
                                   rasterP->chanOffsets);
+        if (rasterP->jdata == NULL) {
+            // unable to verify the raster
+            return -1;
+        }
+        // verify whether channel offsets look sane
+        if (!checkChannelOffsets(rasterP, (*env)->GetArrayLength(env, rasterP->jdata))) {
+            return -1;
+        }
+        break;
+    default:
+        ; // PACKED_RASTER_TYPE does not use the channel offsets.
     }
 
-    /* additioanl check for sppsm fields validity: make sure that
-     * size of raster samples doesn't exceed the data type cpacity.
+    /* additional check for sppsm fields validity: make sure that
+     * size of raster samples doesn't exceed the data type capacity.
      */
     if (rasterP->dataType > UNKNOWN_DATA_TYPE && /* data type has been recognized */
         rasterP->sppsm.maxBitSize > 0 && /* raster has SPP sample model */
@@ -696,6 +781,21 @@
     }
     else if (cmodelP->cmType == DIRECT_CM_TYPE || cmodelP->cmType == PACKED_CM_TYPE) {
         int i;
+
+        /* do some sanity check first: make sure that
+         * - sample model is SinglePixelPackedSampleModel
+         * - number of bands in the raster corresponds to the number
+         *   of color components in the color model
+         */
+        if (!rasterP->sppsm.isUsed ||
+            rasterP->numBands != cmodelP->numComponents)
+        {
+            /* given raster is not compatible with the color model,
+             * so the operation has to be aborted.
+             */
+            return -1;
+        }
+
         if (cmodelP->maxNbits > 8) {
             hintP->needToExpand = TRUE;
             hintP->expandToNbits = cmodelP->maxNbits;
--- a/src/share/native/sun/awt/image/awt_parseImage.h	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/native/sun/awt/image/awt_parseImage.h	Mon Feb 25 08:44:00 2013 +0100
@@ -95,6 +95,7 @@
     jint offsets[MAX_NUMBANDS];
     jint nBits[MAX_NUMBANDS];
     jint  maxBitSize;
+    jint isUsed; // flag to indicate whether the raster sample model is SPPSM
 } SPPSampleModelS_t;
 
 /* Struct that holds information for the Raster object */
--- a/src/share/native/sun/awt/medialib/safe_alloc.h	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/native/sun/awt/medialib/safe_alloc.h	Mon Feb 25 08:44:00 2013 +0100
@@ -41,5 +41,10 @@
     (((w) > 0) && ((h) > 0) && ((sz) > 0) &&                               \
      (((0xffffffffu / ((juint)(w))) / ((juint)(h))) > ((juint)(sz))))
 
+#define SAFE_TO_MULT(a, b) \
+    (((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b)))
+
+#define SAFE_TO_ADD(a, b) \
+    (((a) >= 0) && ((b) >= 0) && ((0x7fffffff - (a)) > (b)))
 
 #endif // __SAFE_ALLOC_H__
--- a/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c	Mon Feb 25 08:44:00 2013 +0100
@@ -133,6 +133,10 @@
     ImageFormat srcFormat;
 
     jpeg_read_header(cinfo, TRUE);
+
+    // SplashScreen jpeg converter expects data in RGB format only
+    cinfo->out_color_space = JCS_RGB;
+
     jpeg_start_decompress(cinfo);
 
     SplashCleanup(splash);
--- a/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java	Mon Feb 25 08:44:00 2013 +0100
@@ -1026,13 +1026,21 @@
                                      boolean unordered,
                                      int ppid)
             throws IOException {
+        InetAddress addr = null;     // no preferred address
+        int port = 0;
+        if (target != null) {
+            InetSocketAddress isa = Net.checkAddress(target);
+            addr = isa.getAddress();
+            port = isa.getPort();
+        }
+
         int pos = bb.position();
         int lim = bb.limit();
         assert (pos <= lim);
         int rem = (pos <= lim ? lim - pos : 0);
 
-        int written = send0(fd, ((DirectBuffer)bb).address() + pos,
-                            rem, target, -1 /*121*/, streamNumber, unordered, ppid);
+        int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
+                            port, -1 /*121*/, streamNumber, unordered, ppid);
         if (written > 0)
             bb.position(pos + written);
         return written;
@@ -1091,7 +1099,7 @@
             long address, int length, boolean peek) throws IOException;
 
     static native int send0(int fd, long address, int length,
-            SocketAddress target, int assocId, int streamNumber,
+            InetAddress addr, int port, int assocId, int streamNumber,
             boolean unordered, int ppid) throws IOException;
 
     private static native int checkConnect(FileDescriptor fd, boolean block,
--- a/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/solaris/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java	Mon Feb 25 08:44:00 2013 +0100
@@ -889,13 +889,20 @@
                                      boolean unordered,
                                      int ppid)
             throws IOException {
+        InetAddress addr = null;     // no preferred address
+        int port = 0;
+        if (target != null) {
+            InetSocketAddress isa = Net.checkAddress(target);
+            addr = isa.getAddress();
+            port = isa.getPort();
+        }
         int pos = bb.position();
         int lim = bb.limit();
         assert (pos <= lim);
         int rem = (pos <= lim ? lim - pos : 0);
 
-        int written = send0(fd, ((DirectBuffer)bb).address() + pos,
-                            rem, target, assocId, streamNumber, unordered, ppid);
+        int written = send0(fd, ((DirectBuffer)bb).address() + pos, rem, addr,
+                            port, assocId, streamNumber, unordered, ppid);
         if (written > 0)
             bb.position(pos + written);
         return written;
@@ -976,13 +983,14 @@
     private static int send0(int fd,
                              long address,
                              int length,
-                             SocketAddress target,
+                             InetAddress addr,
+                             int port,
                              int assocId,
                              int streamNumber,
                              boolean unordered,
                              int ppid)
             throws IOException {
-        return SctpChannelImpl.send0(fd, address, length, target, assocId,
+        return SctpChannelImpl.send0(fd, address, length, addr, port, assocId,
                 streamNumber, unordered, ppid);
     }
 
--- a/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c	Mon Feb 25 08:44:00 2013 +0100
@@ -46,8 +46,6 @@
 
 #include "sun_nio_ch_DatagramChannelImpl.h"
 
-static jfieldID isa_addrID;     /* address in java.net.InetSocketAddress */
-static jfieldID isa_portID;     /* port in java.net.InetSocketAddress */
 static jfieldID dci_senderID;   /* sender in sun.nio.ch.DatagramChannelImpl */
 static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */
 static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */
@@ -61,9 +59,6 @@
     isa_class = (*env)->NewGlobalRef(env, clazz);
     isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>",
                                      "(Ljava/net/InetAddress;I)V");
-    isa_addrID = (*env)->GetFieldID(env, clazz, "addr",
-                                    "Ljava/net/InetAddress;");
-    isa_portID = (*env)->GetFieldID(env, clazz, "port", "I");
 
     clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl");
     dci_senderID = (*env)->GetFieldID(env, clazz, "sender",
@@ -212,15 +207,13 @@
 JNIEXPORT jint JNICALL
 Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
                                           jboolean preferIPv6, jobject fdo, jlong address,
-                                            jint len, jobject dest)
+                                          jint len, jobject destAddress, jint destPort)
 {
     jint fd = fdval(env, fdo);
     void *buf = (void *)jlong_to_ptr(address);
     SOCKADDR sa;
     int sa_len = SOCKADDR_LEN;
     jint n = 0;
-    jobject destAddress = (*env)->GetObjectField(env, dest, isa_addrID);
-    jint destPort = (*env)->GetIntField(env, dest, isa_portID);
 
     if (len > MAX_PACKET_LEN) {
         len = MAX_PACKET_LEN;
--- a/src/solaris/native/sun/nio/ch/sctp/SctpChannelImpl.c	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/solaris/native/sun/nio/ch/sctp/SctpChannelImpl.c	Mon Feb 25 08:44:00 2013 +0100
@@ -67,8 +67,6 @@
 static jmethodID spc_ctrID;    /* sun.nio.ch.sctp.PeerAddressChanged.<init>  */
 static jclass    ss_class;     /* sun.nio.ch.sctp.Shutdown                   */
 static jmethodID ss_ctrID;     /* sun.nio.ch.sctp.Shutdown.<init>            */
-static jfieldID  isa_addrID;   /* java.net.InetSocketAddress.addr            */
-static jfieldID  isa_portID;   /* java.net.InetSocketAddress.port            */
 
 /* defined in SctpNet.c */
 jobject SockAddrToInetSocketAddress(JNIEnv* env, struct sockaddr* addr);
@@ -138,13 +136,6 @@
     CHECK_NULL(ss_class);
     ss_ctrID = (*env)->GetMethodID(env, cls, "<init>", "(I)V");
     CHECK_NULL(ss_ctrID);
-
-    /* InetSocketAddress */
-    cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
-    CHECK_NULL(cls);
-    isa_addrID = (*env)->GetFieldID(env, cls, "addr", "Ljava/net/InetAddress;");
-    CHECK_NULL(isa_addrID);
-    isa_portID = (*env)->GetFieldID(env, cls, "port", "I");
 }
 
 void getControlData
@@ -509,12 +500,12 @@
 /*
  * Class:     sun_nio_ch_sctp_SctpChannelImpl
  * Method:    send0
- * Signature: (IJILjava/net/SocketAddress;IIZI)I
+ * Signature: (IJILjava/net/InetAddress;IIIZI)I
  */
 JNIEXPORT jint JNICALL Java_sun_nio_ch_sctp_SctpChannelImpl_send0
   (JNIEnv *env, jclass klass, jint fd, jlong address, jint length,
-   jobject saTarget, jint assocId, jint streamNumber, jboolean unordered,
-   jint ppid) {
+   jobject targetAddress, jint targetPort, jint assocId, jint streamNumber,
+   jboolean unordered, jint ppid) {
     SOCKADDR sa;
     int sa_len = sizeof(sa);
     ssize_t rv = 0;
@@ -526,17 +517,13 @@
     struct controlData cdata[1];
 
     /* SctpChannel:
-     *    saTarget may contain the preferred address or NULL to use primary,
+     *    targetAddress may contain the preferred address or NULL to use primary,
      *    assocId will always be -1
      * SctpMultiChannell:
-     *    Setup new association, saTarget will contain address, assocId = -1
-     *    Association already existing, assocId != -1, saTarget = preferred addr
+     *    Setup new association, targetAddress will contain address, assocId = -1
+     *    Association already existing, assocId != -1, targetAddress = preferred addr
      */
-    if (saTarget != NULL /*&& assocId <= 0*/) {
-
-        jobject targetAddress = (*env)->GetObjectField(env, saTarget, isa_addrID);
-        jint targetPort = (*env)->GetIntField(env, saTarget, isa_portID);
-
+    if (targetAddress != NULL /*&& assocId <= 0*/) {
         if (NET_InetAddressToSockaddr(env, targetAddress, targetPort,
                                       (struct sockaddr *)&sa,
                                       &sa_len, JNI_TRUE) != 0) {
--- a/src/windows/bin/java_md.c	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/windows/bin/java_md.c	Mon Feb 25 08:44:00 2013 +0100
@@ -101,7 +101,6 @@
 /* funtion in awt.dll (src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp) */
 #define D3D_PRELOAD_FUNC "preloadD3D"
 
-
 /* Extracts value of a parameter with the specified name
  * from command line argument (returns pointer in the argument).
  * Returns NULL if the argument does not contains the parameter.
@@ -276,7 +275,8 @@
 #endif
 #ifdef CRT_DLL
         if (GetJREPath(crtpath, MAXPATHLEN)) {
-            if (JLI_StrLen(crtpath) + JLI_StrLen("\\bin\\") + JLI_StrLen(CRT_DLL) >= MAXPATHLEN) {
+            if (JLI_StrLen(crtpath) + JLI_StrLen("\\bin\\") +
+                    JLI_StrLen(CRT_DLL) >= MAXPATHLEN) {
                 JLI_ReportErrorMessage(JRE_ERROR11);
                 return JNI_FALSE;
             }
@@ -347,7 +347,8 @@
     if (JLI_StrChr(jvmtype, '/') || JLI_StrChr(jvmtype, '\\')) {
         JLI_Snprintf(jvmpath, jvmpathsize, "%s\\" JVM_DLL, jvmtype);
     } else {
-        JLI_Snprintf(jvmpath, jvmpathsize, "%s\\bin\\%s\\" JVM_DLL, jrepath, jvmtype);
+        JLI_Snprintf(jvmpath, jvmpathsize, "%s\\bin\\%s\\" JVM_DLL,
+                     jrepath, jvmtype);
     }
     if (stat(jvmpath, &s) == 0) {
         return JNI_TRUE;
@@ -525,6 +526,37 @@
     }
     return (counts * 1000 * 1000)/counterFrequency.QuadPart;
 }
+/*
+ * windows snprintf does not guarantee a null terminator in the buffer,
+ * if the computed size is equal to or greater than the buffer size,
+ * as well as error conditions. This function guarantees a null terminator
+ * under all these conditions. An unreasonable buffer or size will return
+ * an error value. Under all other conditions this function will return the
+ * size of the bytes actually written minus the null terminator, similar
+ * to ansi snprintf api. Thus when calling this function the caller must
+ * ensure storage for the null terminator.
+ */
+int
+JLI_Snprintf(char* buffer, size_t size, const char* format, ...) {
+    int rc;
+    va_list vl;
+    if (size == 0 || buffer == NULL)
+        return -1;
+    buffer[0] = '\0';
+    va_start(vl, format);
+    rc = vsnprintf(buffer, size, format, vl);
+    va_end(vl);
+    /* force a null terminator, if something is amiss */
+    if (rc < 0) {
+        /* apply ansi semantics */
+        buffer[size - 1] = '\0';
+        return size;
+    } else if (rc == size) {
+        /* force a null terminator */
+        buffer[size - 1] = '\0';
+    }
+    return rc;
+}
 
 void
 JLI_ReportErrorMessage(const char* fmt, ...) {
@@ -880,7 +912,7 @@
  */
 void
 ExecJRE(char *jre, char **argv) {
-    int     len;
+    jint     len;
     char    path[MAXPATHLEN + 1];
 
     const char *progname = GetProgramName();
@@ -1417,7 +1449,10 @@
         // we add the indicator
         tlen = 1 + JLI_StrLen(strv[i]) + 1;
         nargv[i] = (char *) JLI_MemAlloc(tlen);
-        JLI_Snprintf(nargv[i], tlen, "%c%s", arg_expand ? 'T' : 'F', strv[i]);
+        if (JLI_Snprintf(nargv[i], tlen, "%c%s", arg_expand ? 'T' : 'F',
+                         strv[i]) < 0) {
+            return NULL;
+        }
         JLI_TraceLauncher("%s\n", nargv[i]);
     }
 
--- a/src/windows/classes/sun/awt/windows/WComponentPeer.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/windows/classes/sun/awt/windows/WComponentPeer.java	Mon Feb 25 08:44:00 2013 +0100
@@ -488,14 +488,15 @@
                     try {
                         replaceSurfaceData();
                     } catch (InvalidPipeException e) {
-                    // REMIND : what do we do if our surface creation failed?
+                        // REMIND : what do we do if our surface creation failed?
                     }
                 }
             }
         };
+        Component c = (Component)target;
         // Fix 6255371.
-        if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing((Component)target, r)) {
-            postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), r));
+        if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing(c, r)) {
+            postEvent(new InvocationEvent(c, r));
         }
     }
 
@@ -618,7 +619,7 @@
     }
 
     public void disposeLater() {
-        postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), new Runnable() {
+        postEvent(new InvocationEvent(target, new Runnable() {
             public void run() {
                 dispose();
             }
--- a/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/windows/classes/sun/awt/windows/WEmbeddedFrame.java	Mon Feb 25 08:44:00 2013 +0100
@@ -27,6 +27,7 @@
 
 import sun.awt.*;
 import java.awt.*;
+import java.awt.event.InvocationEvent;
 import java.awt.peer.ComponentPeer;
 import java.awt.image.*;
 import sun.awt.image.ByteInterleavedRaster;
@@ -232,11 +233,13 @@
         } else {
             // To avoid focus concurrence b/w IE and EmbeddedFrame
             // activation is postponed by means of posting it to EDT.
-            EventQueue.invokeLater(new Runnable() {
-                    public void run() {
-                        ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true);
-                    }
-                });
+            Runnable r = new Runnable() {
+                public void run() {
+                    ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true);
+                }
+            };
+            WToolkit.postEvent(WToolkit.targetToAppContext(this),
+                               new InvocationEvent(this, r));
         }
     }
 
--- a/src/windows/native/sun/nio/ch/DatagramChannelImpl.c	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/windows/native/sun/nio/ch/DatagramChannelImpl.c	Mon Feb 25 08:44:00 2013 +0100
@@ -34,8 +34,6 @@
 #include "net_util.h"
 #include <winsock2.h>
 
-static jfieldID isa_addrID;     /* address in java.net.InetSocketAddress */
-static jfieldID isa_portID;     /* port in java.net.InetSocketAddress */
 static jfieldID dci_senderID;   /* sender in sun.nio.ch.DatagramChannelImpl */
 static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */
 static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */
@@ -50,9 +48,6 @@
     isa_class = (*env)->NewGlobalRef(env, clazz);
     isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>",
                                      "(Ljava/net/InetAddress;I)V");
-    isa_addrID = (*env)->GetFieldID(env, clazz, "addr",
-                                    "Ljava/net/InetAddress;");
-    isa_portID = (*env)->GetFieldID(env, clazz, "port", "I");
 
     clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl");
     dci_senderID = (*env)->GetFieldID(env, clazz, "sender",
@@ -214,15 +209,14 @@
 JNIEXPORT jint JNICALL
 Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
                                           jboolean preferIPv6, jobject fdo,
-                                          jlong address, jint len, jobject dest)
+                                          jlong address, jint len,
+                                          jobject destAddress, jint destPort)
 {
     jint fd = fdval(env, fdo);
     void *buf = (void *)jlong_to_ptr(address);
     SOCKETADDRESS sa;
     int sa_len;
     jint rv = 0;
-    jobject destAddress = (*env)->GetObjectField(env, dest, isa_addrID);
-    jint destPort = (*env)->GetIntField(env, dest, isa_portID);
 
     if (NET_InetAddressToSockaddr(env, destAddress, destPort,
                                   (struct sockaddr *)&sa,
--- a/src/windows/native/sun/windows/awt_TextComponent.cpp	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/windows/native/sun/windows/awt_TextComponent.cpp	Mon Feb 25 08:44:00 2013 +0100
@@ -53,14 +53,12 @@
  * AwtTextComponent fields
  */
 
-/* java.awt.TextComponent fields */
-jfieldID AwtTextComponent::canAccessClipboardID;
-
-
 /************************************************************************
  * AwtTextComponent methods
  */
 
+jmethodID AwtTextComponent::canAccessClipboardMID;
+
 AwtTextComponent::AwtTextComponent() {
     m_synthetic = FALSE;
     m_lStartPos = -1;
@@ -367,8 +365,7 @@
         }
         jobject target = GetTarget(env);
         jboolean canAccessClipboard =
-            env->GetBooleanField(target,
-                                 AwtTextComponent::canAccessClipboardID);
+            env->CallBooleanMethod (target, AwtTextComponent::canAccessClipboardMID);
         env->DeleteLocalRef(target);
         return (canAccessClipboard) ? mrDoDefault : mrConsume;
     }
@@ -854,12 +851,13 @@
 {
     TRY;
 
-    cls = env->FindClass("java/awt/TextComponent");
-    if (cls != NULL) {
-        AwtTextComponent::canAccessClipboardID =
-            env->GetFieldID(cls, "canAccessClipboard", "Z");
-        DASSERT(AwtTextComponent::canAccessClipboardID != NULL);
-    }
+    jclass textComponentClassID = env->FindClass("java/awt/TextComponent");
+    AwtTextComponent::canAccessClipboardMID =
+        env->GetMethodID(textComponentClassID,
+        "canAccessClipboard", "()Z");
+    env->DeleteLocalRef(textComponentClassID);
+
+    DASSERT(AwtTextComponent::canAccessClipboardMID != NULL);
 
     CATCH_BAD_ALLOC;
 }
--- a/src/windows/native/sun/windows/awt_TextComponent.h	Sat Feb 23 13:32:32 2013 -0800
+++ b/src/windows/native/sun/windows/awt_TextComponent.h	Mon Feb 25 08:44:00 2013 +0100
@@ -42,8 +42,7 @@
 
 class AwtTextComponent : public AwtComponent {
 public:
-    /* java.awt.TextComponent canAccessClipboard field ID */
-    static jfieldID canAccessClipboardID;
+    static jmethodID canAccessClipboardMID;
 
     AwtTextComponent();
 
--- a/test/Makefile	Sat Feb 23 13:32:32 2013 -0800
+++ b/test/Makefile	Mon Feb 25 08:44:00 2013 +0100
@@ -513,6 +513,7 @@
           javax/script \
 	  java/sql javax/sql \
           javax/smartcardio \
+	  javax/xml/soap \
 	  javax/xml/ws com/sun/internal/ws \
 	  jdk/asm \
 	  com/sun/org/apache/xerces \
--- a/test/java/nio/channels/DatagramChannel/SendToUnresolved.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/test/java/nio/channels/DatagramChannel/SendToUnresolved.java	Mon Feb 25 08:44:00 2013 +0100
@@ -42,7 +42,7 @@
         try {
             dc.send(bb, sa);
             throw new RuntimeException("Expected exception not thrown");
-        } catch (IOException e) {
+        } catch (IOException | UnresolvedAddressException e) {
             // Correct result
         }
         dc.close();
--- a/test/java/rmi/server/RMIClassLoader/loadProxyClasses/security.policy	Sat Feb 23 13:32:32 2013 -0800
+++ b/test/java/rmi/server/RMIClassLoader/loadProxyClasses/security.policy	Mon Feb 25 08:44:00 2013 +0100
@@ -13,6 +13,7 @@
     permission java.io.FilePermission ".${/}-", "read,write,delete";
 
     permission java.lang.RuntimePermission "createClassLoader";
+    permission java.lang.RuntimePermission "getClassLoader";
     permission java.lang.RuntimePermission "setContextClassLoader";
 
     // used by TestLibrary to determine test environment
--- a/test/java/rmi/testlibrary/JavaVM.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/test/java/rmi/testlibrary/JavaVM.java	Mon Feb 25 08:44:00 2013 +0100
@@ -110,6 +110,14 @@
         return TestLibrary.getExtraProperty("jcov.options","");
     }
 
+    public void start(Runnable runnable) throws IOException {
+        if (runnable == null) {
+            throw new NullPointerException("Runnable cannot be null.");
+        }
+
+        start();
+        new JavaVMCallbackHandler(runnable).start();
+    }
 
     /**
      * Exec the VM as specified in this object's constructor.
@@ -183,4 +191,35 @@
         start();
         return waitFor();
     }
+
+    /**
+     * Handles calling the callback.
+     */
+    private class JavaVMCallbackHandler extends Thread {
+        Runnable runnable;
+
+        JavaVMCallbackHandler(Runnable runnable) {
+            this.runnable = runnable;
+        }
+
+
+        /**
+         * Wait for the Process to terminate and notify the callback.
+         */
+        @Override
+        public void run() {
+            if (vm != null) {
+                try {
+                    vm.waitFor();
+                } catch(InterruptedException ie) {
+                    // Restore the interrupted status
+                    Thread.currentThread().interrupt();
+                }
+            }
+
+            if (runnable != null) {
+                runnable.run();
+            }
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/logging/CustomLogManager.java	Mon Feb 25 08:44:00 2013 +0100
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2013, 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.*;
+import java.util.*;
+import java.util.logging.*;
+
+/*
+ * Custom LogManager implementation to verify that the implementation delegates
+ * to the LogManager subclass to register both system logger and user logger.
+ *
+ * The LogManager implementation is the one configuring the logger's property
+ * such as level, handler, etc.
+ */
+public class CustomLogManager extends LogManager {
+    static LogManager INSTANCE;
+    Map<String,Logger> namedLoggers = new HashMap<>();
+    Properties props = initConfig();
+    public CustomLogManager() {
+        if (INSTANCE != null) {
+            throw new RuntimeException("CustomLogManager already created");
+        }
+        INSTANCE = this;
+    }
+
+    public synchronized boolean addLogger(Logger logger) {
+        String name = logger.getName();
+        if (namedLoggers.containsKey(name)) {
+            return false;
+        }
+        namedLoggers.put(name, logger);
+        // set level
+        if (props.get(name + ".level") != null) {
+            logger.setLevel(Level.parse(props.getProperty(name + ".level")));
+        }
+        // add handlers
+        if (props.get(name + ".handlers") != null && logger.getHandlers().length == 0) {
+            logger.addHandler(new CustomHandler());
+        }
+        // add parent loggers
+        int ix = 1;
+        for (;;) {
+            int ix2 = name.indexOf(".", ix);
+            if (ix2 < 0) {
+                break;
+            }
+            String pname = name.substring(0, ix2);
+            if (props.get(pname + ".level") != null ||
+                props.get(pname + ".handlers") != null) {
+                // This pname has a level/handlers definition.
+                // Make sure it exists.
+                //
+                // The test doesn't set the parent for simplicity.
+                if (!namedLoggers.containsKey(pname)) {
+                    Logger.getLogger(pname);
+                }
+            }
+            ix = ix2 + 1;
+        }
+        return true;
+    }
+
+    public synchronized Logger getLogger(String name) {
+        return namedLoggers.get(name);
+    }
+
+    public synchronized Enumeration<String> getLoggerNames() {
+        return Collections.enumeration(namedLoggers.keySet());
+    }
+
+    public String getProperty(String name) {
+        return props.getProperty(name);
+    }
+
+    public void readConfiguration() {
+        // do nothing
+    }
+
+    public void readConfiguration(InputStream ins) {
+        // do nothing
+    }
+
+    private Properties initConfig() {
+        Properties props = new Properties();
+        props.put(".level", "CONFIG");
+        props.put("CustomLogManagerTest.level", "WARNING");
+        props.put("CustomLogManagerTest.handlers", "CustomLogManager$CustomHandler");
+        props.put("SimpleLogManager.level", "INFO");
+        props.put("SimpleLogManager.handlers", "CustomLogManager$CustomHandler");
+        props.put("CustomLogManager$CustomHandler.level", "WARNING");
+        props.put(".handlers", "CustomLogManager$CustomHandler");
+        props.put("org.foo.bar.level", "SEVERE");
+        props.put("org.foo.handlers", "CustomLogManager$CustomHandler");
+        props.put("org.openjdk.level", "SEVERE");
+        props.put("org.openjdk.handlers", "CustomLogManager$CustomHandler");
+        props.put("org.openjdk.core.level", "INFO");
+
+        return props;
+    }
+
+    public static void checkLogger(String name) {
+        checkLogger(name, null);
+    }
+
+    public static void checkLogger(String name, String resourceBundleName) {
+        Logger logger = INSTANCE.getLogger(name);
+        if (logger == null) {
+            throw new RuntimeException("Logger \"" + name + "\" not exist");
+        }
+        System.out.format("Logger \"%s\" level=%s handlers=%s resourcebundle=%s%n",
+            name, logger.getLevel(),
+            Arrays.toString(logger.getHandlers()),
+            logger.getResourceBundleName());
+        String rb = logger.getResourceBundleName();
+        if (rb != resourceBundleName && (rb == null || rb.equals(resourceBundleName))) {
+            throw new RuntimeException("Logger \"" + name +
+                "\" unexpected resource bundle: " + rb);
+        }
+
+        String value = INSTANCE.getProperty(name + ".level");
+        String level = logger.getLevel() != null ? logger.getLevel().getName() : null;
+        if (level != value && (level == null || level.equals(value))) {
+            throw new RuntimeException("Logger \"" + name + "\" unexpected level: " + level);
+        }
+
+        Handler[] handlers = logger.getHandlers();
+        String hdl = INSTANCE.getProperty(name + ".handlers");
+        if ((hdl == null && handlers.length != 0) ||
+            (hdl != null && handlers.length != 1)) {
+            throw new RuntimeException("Logger \"" + name + "\" unexpected handler: " +
+                Arrays.toString(handlers));
+        }
+        checkParents(name);
+    }
+
+    private static void checkParents(String name) {
+        int ix = 1;
+        for (;;) {
+            int ix2 = name.indexOf(".", ix);
+            if (ix2 < 0) {
+                break;
+            }
+            String pname = name.substring(0, ix2);
+            if (INSTANCE.getProperty(pname + ".level") != null ||
+                INSTANCE.getProperty(pname + ".handlers") != null) {
+                // This pname has a level/handlers definition.
+                // Make sure it exists.
+                checkLogger(pname);
+            }
+            ix = ix2 + 1;
+        }
+    }
+
+    // only CustomLogManager can create an instance of CustomHandler
+    private class CustomHandler extends StreamHandler {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/logging/CustomLogManagerTest.java	Mon Feb 25 08:44:00 2013 +0100
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013, 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.*;
+import java.util.*;
+
+import java.util.logging.*;
+import sun.util.logging.PlatformLogger;
+
+/*
+ * @test
+ * @bug 8005615
+ * @summary Add loggers to custom log manager
+ *
+ * @compile -XDignore.symbol.file CustomLogManagerTest.java CustomLogManager.java
+ * @run main/othervm -Djava.util.logging.manager=CustomLogManager CustomLogManagerTest
+ */
+public class CustomLogManagerTest {
+    private static final String RESOURCE_BUNDLE = "sun.util.logging.resources.logging";
+    public static void main(String[] args) {
+        String mgr = System.getProperty("java.util.logging.manager");
+        if (!mgr.equals("CustomLogManager")) {
+            throw new RuntimeException("java.util.logging.manager not set");
+        }
+
+        Logger.getLogger(CustomLogManagerTest.class.getName());
+        Logger.getLogger("org.foo.Foo");
+        Logger.getLogger("org.foo.bar.Foo", RESOURCE_BUNDLE);
+        // platform logger will be set with the default system resource bundle
+        PlatformLogger.getLogger("org.openjdk.core.logger");
+
+        if (LogManager.getLogManager() != CustomLogManager.INSTANCE) {
+             throw new RuntimeException(LogManager.getLogManager() + " not CustomLogManager");
+        }
+
+        CustomLogManager.checkLogger(CustomLogManagerTest.class.getName());
+        CustomLogManager.checkLogger("org.foo.Foo");
+        CustomLogManager.checkLogger("org.foo.bar.Foo", RESOURCE_BUNDLE);
+        CustomLogManager.checkLogger(Logger.GLOBAL_LOGGER_NAME);
+        CustomLogManager.checkLogger("");
+        CustomLogManager.checkLogger("org.openjdk.core.logger", RESOURCE_BUNDLE);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/util/logging/SimpleLogManager.java	Mon Feb 25 08:44:00 2013 +0100
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2013, 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.*;
+import java.util.logging.*;
+import sun.util.logging.PlatformLogger;
+
+/*
+ * @test
+ * @bug 8005615
+ * @summary A LogManager subclass overrides its own implementation of named
+ *          logger (see the subclassing information in the Logger class specification)
+ *
+ * @compile -XDignore.symbol.file CustomLogManager.java SimpleLogManager.java
+ * @run main/othervm -Djava.util.logging.manager=SimpleLogManager SimpleLogManager
+ */
+public class SimpleLogManager extends CustomLogManager {
+    public static void main(String[] args) {
+        String classname = System.getProperty("java.util.logging.manager");
+        if (!classname.equals("SimpleLogManager")) {
+            throw new RuntimeException("java.util.logging.manager not set");
+        }
+
+        Logger logger = Logger.getLogger(SimpleLogManager.class.getName());
+        Logger.getLogger("org.foo.bar.Foo");
+
+        // a platform logger used by the system code is just a Logger instance.
+        PlatformLogger.getLogger("org.openjdk.core.logger");
+
+        LogManager mgr = LogManager.getLogManager();
+        if (mgr != CustomLogManager.INSTANCE || !(mgr instanceof SimpleLogManager)) {
+             throw new RuntimeException(LogManager.getLogManager() + " not SimpleLogManager");
+        }
+
+        checkCustomLogger(SimpleLogManager.class.getName(), null);
+        checkCustomLogger("org.foo.bar.Foo", null);
+        checkCustomLogger("org.openjdk.core.logger", "sun.util.logging.resources.logging");
+
+        // ## The LogManager.demandLogger method does not handle custom log manager
+        // ## that overrides the getLogger method to return a custom logger
+        // ## (see the test case in 8005640).  Logger.getLogger may return
+        // ## a Logger instance but LogManager overrides it with a custom Logger
+        // ## instance like this case.
+        //
+        // However, the specification of LogManager and Logger subclassing is
+        // not clear whether this is supported or not.  The following check
+        // just captures the current behavior.
+        if (logger instanceof CustomLogger) {
+            throw new RuntimeException(logger + " not CustomLogger");
+        }
+    }
+
+    private static void checkCustomLogger(String name, String resourceBundleName) {
+        CustomLogManager.checkLogger(name, resourceBundleName);
+        Logger logger1 = Logger.getLogger(name);
+        Logger logger2 = LogManager.getLogManager().getLogger(name);
+        if (logger1 != logger2) {
+            throw new RuntimeException(logger1 + " != " + logger2);
+        }
+        if (!(logger1 instanceof CustomLogger)) {
+            throw new RuntimeException(logger1 + " not CustomLogger");
+        }
+    }
+
+    /*
+     * This SimpleLogManager overrides the addLogger method to replace
+     * the given logger with a custom logger.
+     *
+     * It's unclear what the recommended way to use custom logger is.
+     * A LogManager subclass might override the getLogger method to return
+     * a custom Logger and create a new custom logger if not exist so that
+     * Logger.getLogger() can return a custom Logger instance but that violates
+     * the LogManager.getLogger() spec which should return null if not found.
+     */
+    public synchronized boolean addLogger(Logger logger) {
+        String name = logger.getName();
+        if (namedLoggers.containsKey(name)) {
+            return false;
+        }
+        CustomLogger newLogger = new CustomLogger(logger);
+        super.addLogger(newLogger);
+        return true;
+    }
+
+    public class CustomLogger extends Logger {
+        CustomLogger(Logger logger) {
+            super(logger.getName(), logger.getResourceBundleName());
+        }
+        CustomLogger(String name) {
+            super(name, null);
+        }
+    }
+}
--- a/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java	Mon Feb 25 08:44:00 2013 +0100
@@ -119,9 +119,6 @@
             System.out.println("Create SimpleStandard MBean");
             SimpleStandard s = new SimpleStandard("monitorRole");
             mbs.registerMBean(s, new ObjectName("MBeans:type=SimpleStandard"));
-            // Set Security Manager
-            //
-            System.setSecurityManager(new SecurityManager());
             // Create Properties containing the username/password entries
             //
             Properties props = new Properties();
@@ -132,6 +129,9 @@
             HashMap env = new HashMap();
             env.put("jmx.remote.authenticator",
                     new JMXPluggableAuthenticator(props));
+            // Set Security Manager
+            //
+            System.setSecurityManager(new SecurityManager());
             // Create an RMI connector server
             //
             System.out.println("Create an RMI connector server");
--- a/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java	Mon Feb 25 08:44:00 2013 +0100
@@ -120,9 +120,6 @@
             System.out.println("Create SimpleStandard MBean");
             SimpleStandard s = new SimpleStandard("delegate");
             mbs.registerMBean(s, new ObjectName("MBeans:type=SimpleStandard"));
-            // Set Security Manager
-            //
-            System.setSecurityManager(new SecurityManager());
             // Create Properties containing the username/password entries
             //
             Properties props = new Properties();
@@ -133,6 +130,9 @@
             HashMap env = new HashMap();
             env.put("jmx.remote.authenticator",
                     new JMXPluggableAuthenticator(props));
+            // Set Security Manager
+            //
+            System.setSecurityManager(new SecurityManager());
             // Create an RMI connector server
             //
             System.out.println("Create an RMI connector server");
--- a/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java	Mon Feb 25 08:44:00 2013 +0100
@@ -29,7 +29,7 @@
 import javax.net.ssl.*;
 import java.lang.reflect.*;
 
-import sun.security.util.KeyLength;
+import sun.security.util.KeyUtil;
 
 public class ShortRSAKeyWithinTLS {
 
@@ -175,13 +175,13 @@
             privateKey = (PrivateKey)ks.getKey(keyAlias, null);
             publicKey = (PublicKey)ks.getCertificate(keyAlias).getPublicKey();
 
-            int privateKeySize = KeyLength.getKeySize(privateKey);
+            int privateKeySize = KeyUtil.getKeySize(privateKey);
             if (privateKeySize != keySize) {
                 throw new Exception("Expected key size is " + keySize +
                         ", but the private key size is " + privateKeySize);
             }
 
-            int publicKeySize = KeyLength.getKeySize(publicKey);
+            int publicKeySize = KeyUtil.getKeySize(publicKey);
             if (publicKeySize != keySize) {
                 throw new Exception("Expected key size is " + keySize +
                         ", but the public key size is " + publicKeySize);
--- a/test/tools/launcher/ToolsOpts.java	Sat Feb 23 13:32:32 2013 -0800
+++ b/test/tools/launcher/ToolsOpts.java	Mon Feb 25 08:44:00 2013 +0100
@@ -23,6 +23,7 @@
 
 /*
  * @test
+ * @bug 8002091
  * @summary Test options patterns for javac,javah,javap and javadoc using
  * javac as a test launcher. Create a dummy javac and intercept options to check
  * reception of options as passed through the launcher without having to launch