changeset 4668:3b517c0d6b74

Merge
author asaha
date Fri, 24 Jun 2011 17:36:48 -0700
parents f097ca2434b1 (current diff) 69e973991866 (diff)
children c383f3c8ccce
files
diffstat 8 files changed, 182 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java	Wed Jun 22 12:41:14 2011 -0700
+++ b/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java	Fri Jun 24 17:36:48 2011 -0700
@@ -29,6 +29,7 @@
 import sun.org.mozilla.javascript.internal.*;
 import java.lang.reflect.Method;
 import java.io.*;
+import java.security.*;
 import java.util.*;
 
 
@@ -45,6 +46,8 @@
 
     private static final boolean DEBUG = false;
 
+    private AccessControlContext accCtxt;
+
     /* Scope where standard JavaScript objects and our
      * extensions to it are stored. Note that these are not
      * user defined engine level global variables. These are
@@ -63,8 +66,13 @@
 
     private static final int languageVersion = getLanguageVersion();
     private static final int optimizationLevel = getOptimizationLevel();
+
     static {
         ContextFactory.initGlobal(new ContextFactory() {
+            /**
+             * Create new Context instance to be associated with the current thread.
+             */
+            @Override
             protected Context makeContext() {
                 Context cx = super.makeContext();
                 cx.setLanguageVersion(languageVersion);
@@ -73,6 +81,40 @@
                 cx.setWrapFactory(RhinoWrapFactory.getInstance());
                 return cx;
             }
+
+            /**
+             * Execute top call to script or function. When the runtime is about to
+             * execute a script or function that will create the first stack frame
+             * with scriptable code, it calls this method to perform the real call.
+             * In this way execution of any script happens inside this function.
+             */
+            @Override
+            protected Object doTopCall(final Callable callable,
+                               final Context cx, final Scriptable scope,
+                               final Scriptable thisObj, final Object[] args) {
+                AccessControlContext accCtxt = null;
+                Scriptable global = ScriptableObject.getTopLevelScope(scope);
+                Scriptable globalProto = global.getPrototype();
+                if (globalProto instanceof RhinoTopLevel) {
+                    accCtxt = ((RhinoTopLevel)globalProto).getAccessContext();
+                }
+
+                if (accCtxt != null) {
+                    return AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                        public Object run() {
+                            return superDoTopCall(callable, cx, scope, thisObj, args);
+                        }
+                    }, accCtxt);
+                } else {
+                    return superDoTopCall(callable, cx, scope, thisObj, args);
+                }
+            }
+
+            private  Object superDoTopCall(Callable callable,
+                               Context cx, Scriptable scope,
+                               Scriptable thisObj, Object[] args) {
+                return super.doTopCall(callable, cx, scope, thisObj, args);
+            }
         });
     }
 
@@ -103,6 +145,9 @@
      * Creates a new instance of RhinoScriptEngine
      */
     public RhinoScriptEngine() {
+        if (System.getSecurityManager() != null) {
+            accCtxt = AccessController.getContext();
+        }
 
         Context cx = enterContext();
         try {
@@ -360,6 +405,10 @@
         factory = fac;
     }
 
+    AccessControlContext getAccessContext() {
+        return accCtxt;
+    }
+
     Object[] wrapArguments(Object[] args) {
         if (args == null) {
             return Context.emptyArgs;
--- a/src/share/classes/com/sun/script/javascript/RhinoTopLevel.java	Wed Jun 22 12:41:14 2011 -0700
+++ b/src/share/classes/com/sun/script/javascript/RhinoTopLevel.java	Fri Jun 24 17:36:48 2011 -0700
@@ -27,6 +27,7 @@
 
 import sun.org.mozilla.javascript.internal.*;
 import javax.script.*;
+import java.security.AccessControlContext;
 
 /**
  * This class serves as top level scope for Rhino. This class adds
@@ -38,10 +39,12 @@
  */
 public final class RhinoTopLevel extends ImporterTopLevel {
     RhinoTopLevel(Context cx, RhinoScriptEngine engine) {
-        super(cx);
+        // second boolean parameter to super constructor tells whether
+        // to seal standard JavaScript objects or not. If security manager
+        // is present, we seal the standard objects.
+        super(cx, System.getSecurityManager() != null);
         this.engine = engine;
 
-
         // initialize JSAdapter lazily. Reduces footprint & startup time.
         new LazilyLoadedCtor(this, "JSAdapter",
                 "com.sun.script.javascript.JSAdapter",
@@ -152,5 +155,9 @@
         return engine;
     }
 
+    AccessControlContext getAccessContext() {
+        return engine.getAccessContext();
+    }
+
     private RhinoScriptEngine engine;
 }
--- a/src/share/classes/java/awt/AWTKeyStroke.java	Wed Jun 22 12:41:14 2011 -0700
+++ b/src/share/classes/java/awt/AWTKeyStroke.java	Fri Jun 24 17:36:48 2011 -0700
@@ -25,6 +25,7 @@
 package java.awt;
 
 import java.awt.event.KeyEvent;
+import sun.awt.AppContext;
 import java.awt.event.InputEvent;
 import java.util.Collections;
 import java.util.HashMap;
@@ -66,9 +67,6 @@
 public class AWTKeyStroke implements Serializable {
     static final long serialVersionUID = -6430539691155161871L;
 
-    private static Map cache;
-    private static AWTKeyStroke cacheKey;
-    private static Constructor ctor = getCtor(AWTKeyStroke.class);
     private static Map modifierKeywords;
     /**
      * Associates VK_XXX (as a String) with code (as Integer). This is
@@ -77,6 +75,26 @@
      */
     private static VKCollection vks;
 
+    //A key for the collection of AWTKeyStrokes within AppContext.
+    private static Object APP_CONTEXT_CACHE_KEY = new Object();
+    //A key withing the cache
+    private static AWTKeyStroke APP_CONTEXT_KEYSTROKE_KEY = new AWTKeyStroke();
+
+    /*
+     * Reads keystroke class from AppContext and if null, puts there the
+     * AWTKeyStroke class.
+     * Must be called under locked AWTKeyStroke.class
+     */
+    private static Class getAWTKeyStrokeClass() {
+        AppContext appContext = AppContext.getAppContext();
+        Class clazz = (Class)appContext.get(AWTKeyStroke.class);
+        if (clazz == null) {
+            clazz = AWTKeyStroke.class;
+            appContext.put(AWTKeyStroke.class, AWTKeyStroke.class);
+        }
+        return clazz;
+    }
+
     private char keyChar = KeyEvent.CHAR_UNDEFINED;
     private int keyCode = KeyEvent.VK_UNDEFINED;
     private int modifiers;
@@ -164,9 +182,13 @@
         if (subclass == null) {
             throw new IllegalArgumentException("subclass cannot be null");
         }
-        if (AWTKeyStroke.ctor.getDeclaringClass().equals(subclass)) {
-            // Already registered
-            return;
+        AppContext appContext = AppContext.getAppContext();
+        synchronized (AWTKeyStroke.class) {
+            Class keyStrokeClass = (Class)appContext.get(AWTKeyStroke.class);
+            if (keyStrokeClass != null && keyStrokeClass.equals(subclass)){
+                // Already registered
+                return;
+            }
         }
         if (!AWTKeyStroke.class.isAssignableFrom(subclass)) {
             throw new ClassCastException("subclass is not derived from AWTKeyStroke");
@@ -197,9 +219,9 @@
         }
 
         synchronized (AWTKeyStroke.class) {
-            AWTKeyStroke.ctor = ctor;
-            cache = null;
-            cacheKey = null;
+            appContext.put(AWTKeyStroke.class, subclass);
+            appContext.remove(APP_CONTEXT_CACHE_KEY);
+            appContext.remove(APP_CONTEXT_KEYSTROKE_KEY);
         }
     }
 
@@ -229,13 +251,20 @@
     private static synchronized AWTKeyStroke getCachedStroke
         (char keyChar, int keyCode, int modifiers, boolean onKeyRelease)
     {
+        AppContext appContext = AppContext.getAppContext();
+        Map cache = (Map)appContext.get(APP_CONTEXT_CACHE_KEY);
+        AWTKeyStroke cacheKey = (AWTKeyStroke)appContext.get(APP_CONTEXT_KEYSTROKE_KEY);
+
         if (cache == null) {
             cache = new HashMap();
+            appContext.put(APP_CONTEXT_CACHE_KEY, cache);
         }
 
         if (cacheKey == null) {
             try {
-                cacheKey = (AWTKeyStroke)ctor.newInstance((Object[]) null);
+                Class clazz = getAWTKeyStrokeClass();
+                cacheKey = (AWTKeyStroke)getCtor(clazz).newInstance((Object[]) null);
+                appContext.put(APP_CONTEXT_KEYSTROKE_KEY, cacheKey);
             } catch (InstantiationException e) {
                 assert(false);
             } catch (IllegalAccessException e) {
@@ -253,9 +282,8 @@
         if (stroke == null) {
             stroke = cacheKey;
             cache.put(stroke, stroke);
-            cacheKey = null;
+            appContext.remove(APP_CONTEXT_KEYSTROKE_KEY);
         }
-
         return stroke;
     }
 
@@ -777,10 +805,7 @@
      */
     protected Object readResolve() throws java.io.ObjectStreamException {
         synchronized (AWTKeyStroke.class) {
-            Class newClass = getClass();
-            if (!newClass.equals(ctor.getDeclaringClass())) {
-                registerSubclass(newClass);
-            }
+            registerSubclass(getAWTKeyStrokeClass());
             return getCachedStroke(keyChar, keyCode, modifiers, onKeyRelease);
         }
     }
--- a/src/share/classes/java/io/InputStream.java	Wed Jun 22 12:41:14 2011 -0700
+++ b/src/share/classes/java/io/InputStream.java	Fri Jun 24 17:36:48 2011 -0700
@@ -44,10 +44,9 @@
  */
 public abstract class InputStream implements Closeable {
 
-    // SKIP_BUFFER_SIZE is used to determine the size of skipBuffer
-    private static final int SKIP_BUFFER_SIZE = 2048;
-    // skipBuffer is initialized in skip(long), if needed.
-    private static byte[] skipBuffer;
+    // MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to
+    // use when skipping.
+    private static final int MAX_SKIP_BUFFER_SIZE = 2048;
 
     /**
      * Reads the next byte of data from the input stream. The value byte is
@@ -212,18 +211,15 @@
 
         long remaining = n;
         int nr;
-        if (skipBuffer == null)
-            skipBuffer = new byte[SKIP_BUFFER_SIZE];
-
-        byte[] localSkipBuffer = skipBuffer;
 
         if (n <= 0) {
             return 0;
         }
 
+        int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
+        byte[] skipBuffer = new byte[size];
         while (remaining > 0) {
-            nr = read(localSkipBuffer, 0,
-                      (int) Math.min(SKIP_BUFFER_SIZE, remaining));
+            nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
             if (nr < 0) {
                 break;
             }
--- a/src/share/classes/sun/net/ResourceManager.java	Wed Jun 22 12:41:14 2011 -0700
+++ b/src/share/classes/sun/net/ResourceManager.java	Fri Jun 24 17:36:48 2011 -0700
@@ -41,13 +41,14 @@
 
     /* default maximum number of udp sockets per VM
      * when a security manager is enabled.
-     * The default is 1024 which is high enough to be useful
+     * The default is 25 which is high enough to be useful
      * but low enough to be well below the maximum number
-     * of port numbers actually available on all OSes for
-     * such sockets (5000 on some versions of windows)
+     * of port numbers actually available on all OSes
+     * when multiplied by the maximum feasible number of VM processes
+     * that could practically be spawned.
      */
 
-    private static final int DEFAULT_MAX_SOCKETS = 1024;
+    private static final int DEFAULT_MAX_SOCKETS = 25;
     private static final int maxSockets;
     private static final AtomicInteger numSockets;
 
--- a/src/share/native/sun/java2d/loops/TransformHelper.c	Wed Jun 22 12:41:14 2011 -0700
+++ b/src/share/native/sun/java2d/loops/TransformHelper.c	Fri Jun 24 17:36:48 2011 -0700
@@ -284,7 +284,7 @@
     TransformHelperFunc *pHelperFunc;
     TransformInterpFunc *pInterpFunc;
     jdouble xorig, yorig;
-    jint numedges;
+    jlong numedges;
     jint *pEdges;
     jint edgebuf[2 + MAXEDGES * 2];
     union {
@@ -379,19 +379,44 @@
     }
     Region_IntersectBounds(&clipInfo, &dstInfo.bounds);
 
-    numedges = (dstInfo.bounds.y2 - dstInfo.bounds.y1);
-    if (numedges > MAXEDGES) {
-        pEdges = malloc((2 + 2 * numedges) * sizeof (*pEdges));
-        if (pEdges == NULL) {
-            SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
-            SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
-            /* edgeArray should already contain zeros for min/maxy */
-            return;
-        }
+    numedges = (((jlong) dstInfo.bounds.y2) - ((jlong) dstInfo.bounds.y1));
+    if (numedges <= 0) {
+        pEdges = NULL;
+    } else if (!JNU_IsNull(env, edgeArray)) {
+        /*
+         * Ideally Java should allocate an array large enough, but if
+         * we ever have a miscommunication about the number of edge
+         * lines, or if the Java array calculation should overflow to
+         * a positive number and succeed in allocating an array that
+         * is too small, we need to verify that it can still hold the
+         * number of integers that we plan to store to be safe.
+         */
+        jsize edgesize = (*env)->GetArrayLength(env, edgeArray);
+        /* (edgesize/2 - 1) should avoid any overflow or underflow. */
+        pEdges = (((edgesize / 2) - 1) >= numedges)
+            ? (*env)->GetPrimitiveArrayCritical(env, edgeArray, NULL)
+            : NULL;
+    } else if (numedges > MAXEDGES) {
+        /* numedges variable (jlong) can be at most ((1<<32)-1) */
+        /* memsize can overflow a jint, but not a jlong */
+        jlong memsize = ((numedges * 2) + 2) * sizeof(*pEdges);
+        pEdges = (memsize == ((size_t) memsize))
+            ? malloc((size_t) memsize)
+            : NULL;
     } else {
         pEdges = edgebuf;
     }
 
+    if (pEdges == NULL) {
+        if (numedges > 0) {
+            JNU_ThrowInternalError(env, "Unable to allocate edge list");
+        }
+        SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
+        SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
+        /* edgeArray should already contain zeros for min/maxy */
+        return;
+    }
+
     Transform_GetInfo(env, itxform, &itxInfo);
 
     if (!Region_IsEmpty(&clipInfo)) {
@@ -500,14 +525,13 @@
     } else {
         pEdges[0] = pEdges[1] = 0;
     }
+    if (!JNU_IsNull(env, edgeArray)) {
+        (*env)->ReleasePrimitiveArrayCritical(env, edgeArray, pEdges, 0);
+    } else if (pEdges != edgebuf) {
+        free(pEdges);
+    }
     SurfaceData_InvokeUnlock(env, dstOps, &dstInfo);
     SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
-    if (!JNU_IsNull(env, edgeArray)) {
-        (*env)->SetIntArrayRegion(env, edgeArray, 0, 2+numedges*2, pEdges);
-    }
-    if (pEdges != edgebuf) {
-        free(pEdges);
-    }
 }
 
 static void
--- a/src/windows/native/sun/windows/awt_Window.cpp	Wed Jun 22 12:41:14 2011 -0700
+++ b/src/windows/native/sun/windows/awt_Window.cpp	Fri Jun 24 17:36:48 2011 -0700
@@ -355,7 +355,7 @@
     RECT rect;
     CalculateWarningWindowBounds(env, &rect);
 
-    ::SetWindowPos(warningWindow, IsAlwaysOnTop() ? HWND_TOPMOST : GetHWnd(),
+    ::SetWindowPos(warningWindow, IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST,
             rect.left, rect.top,
             rect.right - rect.left, rect.bottom - rect.top,
             SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE |
@@ -835,7 +835,7 @@
 
     if (securityAnimationKind == akShow) {
         ::SetWindowPos(warningWindow,
-                IsAlwaysOnTop() ? HWND_TOPMOST : GetHWnd(),
+                IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST,
                 0, 0, 0, 0,
                 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE |
                 SWP_SHOWWINDOW | SWP_NOOWNERZORDER);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/java2d/loops/TransformOverflow.java	Fri Jun 24 17:36:48 2011 -0700
@@ -0,0 +1,30 @@
+/**
+ * @test %W% %E%
+ * @bug 7023640
+ * @summary Checks for malloc overflow when we transform an image
+ *          into a really tall destination
+ * @run main/othervm/timeout=5000 -Xmx1g TransformOverflow
+ */
+
+import java.awt.image.BufferedImage;
+import java.awt.Graphics2D;
+
+public class TransformOverflow {
+    public static void main(String argv[]) {
+        test(1, 0x20000000);
+        System.out.println("done");
+    }
+
+    public static void test(int w, int h) {
+        BufferedImage bimg =
+            new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
+        Graphics2D g2d = bimg.createGraphics();
+        g2d.scale(1.0, Math.PI);
+        g2d.shear(0.0, 1.0);
+        try {
+            g2d.drawImage(bimg, 0, 0, null);
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+    }
+}