Mercurial > hg > release > icedtea7-forest-2.1 > jdk
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(); + } + } +}