/** * This method actually creates an AppletClassLoader. * * It can be override by subclasses (such as the Plug-in) * to provide different classloaders. */ protected AppletClassLoader createClassLoader(final URL codebase) { return new AppletClassLoader(codebase); } /** * Get a class loader. Create in a restricted context */ synchronized AppletClassLoader getClassLoader(final URL codebase, final String key) { AppletClassLoader c = (AppletClassLoader)classloaders.get(key); if (c == null) { AccessControlContext acc = getAccessControlContext(codebase); c = (AppletClassLoader) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { AppletClassLoader ac = createClassLoader(codebase); /* Should the creation of the classloader be * within the class synchronized block? Since * this class is used by the plugin, take care * to avoid deadlocks, or specialize * AppletPanel within the plugin. It may take * an arbitrary amount of time to create a * class loader (involving getting Jar files * etc.) and may block unrelated applets from * finishing createAppletThread (due to the * class synchronization). If * createAppletThread does not finish quickly, * the applet cannot process other messages, * particularly messages such as destroy * (which timeout when called from the browser). */ synchronized (getClass()) { AppletClassLoader res = (AppletClassLoader)classloaders.get(key); if (res == null) { classloaders.put(key, ac); return ac; } else { return res; } } } },acc); } return c; } /** * get the context for the AppletClassLoader we are creating. * the context is granted permission to create the class loader, * connnect to the codebase, and whatever else the policy grants * to all codebases. */ private AccessControlContext getAccessControlContext(final URL codebase) { PermissionCollection perms = (PermissionCollection) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { Policy p = java.security.Policy.getPolicy(); if (p != null) { return p.getPermissions(new CodeSource(null, (java.security.cert.Certificate[]) null)); } else { return null; } } }); if (perms == null) perms = new Permissions(); //XXX: this is needed to be able to create the classloader itself! perms.add(SecurityConstants.CREATE_CLASSLOADER_PERMISSION); Permission p; java.net.URLConnection urlConnection = null; try { urlConnection = codebase.openConnection(); p = urlConnection.getPermission(); } catch (java.io.IOException ioe) { p = null; } if (p != null) perms.add(p); if (p instanceof FilePermission) { String path = p.getName(); int endIndex = path.lastIndexOf(File.separatorChar); if (endIndex != -1) { path = path.substring(0, endIndex+1); if (path.endsWith(File.separator)) { path += "-"; } perms.add(new FilePermission(path, SecurityConstants.FILE_READ_ACTION)); } } else { URL locUrl = codebase; if (urlConnection instanceof JarURLConnection) { locUrl = ((JarURLConnection)urlConnection).getJarFileURL(); } String host = locUrl.getHost(); if (host != null && (host.length() > 0)) perms.add(new SocketPermission(host, SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION)); } ProtectionDomain domain = new ProtectionDomain(new CodeSource(codebase, (java.security.cert.Certificate[]) null), perms); AccessControlContext acc = new AccessControlContext(new ProtectionDomain[] { domain }); return acc; } public Thread getAppletHandlerThread() { return handler; } public int getAppletWidth() { return currentAppletSize.width; } public int getAppletHeight() { return currentAppletSize.height; } public static void changeFrameAppContext(Frame frame, AppContext newAppContext) { // Fixed #4754451: Applet can have methods running on main // thread event queue. // // The cause of this bug is that the frame of the applet // is created in main thread group. Thus, when certain // AWT/Swing events are generated, the events will be // dispatched through the wrong event dispatch thread. // // To fix this, we rearrange the AppContext with the frame, // so the proper event queue will be looked up. // // Swing also maintains a Frame list for the AppContext, // so we will have to rearrange it as well. // Check if frame's AppContext has already been set properly AppContext oldAppContext = SunToolkit.targetToAppContext(frame); if (oldAppContext == newAppContext) return; // Synchronization on Window.class is needed for locking the // critical section of the window list in AppContext. synchronized (Window.class) { WeakReference weakRef = null; // Remove frame from the Window list in wrong AppContext { // Lookup current frame's AppContext Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>)oldAppContext.get(Window.class); if (windowList != null) { for (WeakReference ref : windowList) { if (ref.get() == frame) { weakRef = ref; break; } } // Remove frame from wrong AppContext if (weakRef != null) windowList.remove(weakRef); } } // Put the frame into the applet's AppContext map SunToolkit.insertTargetMapping(frame, newAppContext); // Insert frame into the Window list in the applet's AppContext map { Vector<WeakReference<Window>> windowList = (Vector)newAppContext.get(Window.class); if (windowList == null) { windowList = new Vector<WeakReference<Window>>(); newAppContext.put(Window.class, windowList); } // use the same weakRef here as it is used elsewhere windowList.add(weakRef); } } } // Flag to indicate if applet is targeted for JDK 1.1. private boolean jdk11Applet = false; // Flag to indicate if applet is targeted for JDK 1.2. private boolean jdk12Applet = false; /** * Determine JDK level of an applet. */ private void findAppletJDKLevel(Applet applet) { // To determine the JDK level of an applet, the // most reliable way is to check the major version // of the applet class file. // synchronized on applet class object, so calling from // different instances of the same applet will be // serialized. Class appletClass = applet.getClass(); synchronized(appletClass) { // Determine if the JDK level of an applet has been // checked before. Boolean jdk11Target = (Boolean) loader.isJDK11Target(appletClass); Boolean jdk12Target = (Boolean) loader.isJDK12Target(appletClass); // if applet JDK level has been checked before, retrieve // value and return. if (jdk11Target != null || jdk12Target != null) { jdk11Applet = (jdk11Target == null) ? false : jdk11Target.booleanValue(); jdk12Applet = (jdk12Target == null) ? false : jdk12Target.booleanValue(); return; } String name = appletClass.getName(); // first convert any '.' to '/' name = name.replace('.', '/'); // append .class final String resourceName = name + ".class"; InputStream is = null; byte[] classHeader = new byte[8]; try { is = (InputStream) java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { return loader.getResourceAsStream(resourceName); } }); // Read the first 8 bytes of the class file int byteRead = is.read(classHeader, 0, 8); is.close(); // return if the header is not read in entirely // for some reasons. if (byteRead != 8) return; } catch (IOException e) { return; } // Check major version in class file header int major_version = readShort(classHeader, 6); // Major version in class file is as follows: // 45 - JDK 1.1 // 46 - JDK 1.2 // 47 - JDK 1.3 // 48 - JDK 1.4 // 49 - JDK 1.5 if (major_version < 46) jdk11Applet = true; else if (major_version == 46) jdk12Applet = true; // Store applet JDK level in AppContext for later lookup, // e.g. page switch. loader.setJDK11Target(appletClass, jdk11Applet); loader.setJDK12Target(appletClass, jdk12Applet); } } /** * Return true if applet is targeted to JDK 1.1. */ protected boolean isJDK11Applet() { return jdk11Applet; } /** * Return true if applet is targeted to JDK1.2. */ protected boolean isJDK12Applet() { return jdk12Applet; } /** * Read short from byte array. */ private int readShort(byte[] b, int off) { int hi = readByte(b[off]); int lo = readByte(b[off + 1]); return (hi << 8) | lo; } private int readByte(byte b) { return ((int)b) & 0xFF; } private static AppletMessageHandler amh = new AppletMessageHandler("appletpanel");}Lines 1001–1318 of 1318. Previous lines
/** * This method actually creates an AppletClassLoader. * * It can be override by subclasses (such as the Plug-in) * to provide different classloaders. */ protected AppletClassLoader createClassLoader(final URL codebase) { return new AppletClassLoader(codebase); } /** * Get a class loader. Create in a restricted context */ synchronized AppletClassLoader getClassLoader(final URL codebase, final String key) { AppletClassLoader c = (AppletClassLoader)classloaders.get(key); if (c == null) { AccessControlContext acc = getAccessControlContext(codebase); c = (AppletClassLoader) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { AppletClassLoader ac = createClassLoader(codebase); /* Should the creation of the classloader be * within the class synchronized block? Since * this class is used by the plugin, take care * to avoid deadlocks, or specialize * AppletPanel within the plugin. It may take * an arbitrary amount of time to create a * class loader (involving getting Jar files * etc.) and may block unrelated applets from * finishing createAppletThread (due to the * class synchronization). If * createAppletThread does not finish quickly, * the applet cannot process other messages, * particularly messages such as destroy * (which timeout when called from the browser). */ synchronized (getClass()) { AppletClassLoader res = (AppletClassLoader)classloaders.get(key); if (res == null) { classloaders.put(key, ac); return ac; } else { return res; } } } },acc); } return c; } /** * get the context for the AppletClassLoader we are creating. * the context is granted permission to create the class loader, * connnect to the codebase, and whatever else the policy grants * to all codebases. */ private AccessControlContext getAccessControlContext(final URL codebase) { PermissionCollection perms = (PermissionCollection) AccessController.doPrivileged(new PrivilegedAction() { public Object run() { Policy p = java.security.Policy.getPolicy(); if (p != null) { return p.getPermissions(new CodeSource(null, (java.security.cert.Certificate[]) null)); } else { return null; } } }); if (perms == null) perms = new Permissions(); //XXX: this is needed to be able to create the classloader itself! perms.add(SecurityConstants.CREATE_CLASSLOADER_PERMISSION); Permission p; java.net.URLConnection urlConnection = null; try { urlConnection = codebase.openConnection(); p = urlConnection.getPermission(); } catch (java.io.IOException ioe) { p = null; } if (p != null) perms.add(p); if (p instanceof FilePermission) { String path = p.getName(); int endIndex = path.lastIndexOf(File.separatorChar); if (endIndex != -1) { path = path.substring(0, endIndex+1); if (path.endsWith(File.separator)) { path += "-"; } perms.add(new FilePermission(path, SecurityConstants.FILE_READ_ACTION)); } } else { URL locUrl = codebase; if (urlConnection instanceof JarURLConnection) { locUrl = ((JarURLConnection)urlConnection).getJarFileURL(); } String host = locUrl.getHost(); if (host != null && (host.length() > 0)) perms.add(new SocketPermission(host, SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION)); } ProtectionDomain domain = new ProtectionDomain(new CodeSource(codebase, (java.security.cert.Certificate[]) null), perms); AccessControlContext acc = new AccessControlContext(new ProtectionDomain[] { domain }); return acc; } public Thread getAppletHandlerThread() { return handler; } public int getAppletWidth() { return currentAppletSize.width; } public int getAppletHeight() { return currentAppletSize.height; } public static void changeFrameAppContext(Frame frame, AppContext newAppContext) { // Fixed #4754451: Applet can have methods running on main // thread event queue. // // The cause of this bug is that the frame of the applet // is created in main thread group. Thus, when certain // AWT/Swing events are generated, the events will be // dispatched through the wrong event dispatch thread. // // To fix this, we rearrange the AppContext with the frame, // so the proper event queue will be looked up. // // Swing also maintains a Frame list for the AppContext, // so we will have to rearrange it as well. // Check if frame's AppContext has already been set properly AppContext oldAppContext = SunToolkit.targetToAppContext(frame); if (oldAppContext == newAppContext) return; // Synchronization on Window.class is needed for locking the // critical section of the window list in AppContext. synchronized (Window.class) { WeakReference weakRef = null; // Remove frame from the Window list in wrong AppContext { // Lookup current frame's AppContext Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>)oldAppContext.get(Window.class); if (windowList != null) { for (WeakReference ref : windowList) { if (ref.get() == frame) { weakRef = ref; break; } } // Remove frame from wrong AppContext if (weakRef != null) windowList.remove(weakRef); } } // Put the frame into the applet's AppContext map SunToolkit.insertTargetMapping(frame, newAppContext); // Insert frame into the Window list in the applet's AppContext map { Vector<WeakReference<Window>> windowList = (Vector)newAppContext.get(Window.class); if (windowList == null) { windowList = new Vector<WeakReference<Window>>(); newAppContext.put(Window.class, windowList); } // use the same weakRef here as it is used elsewhere windowList.add(weakRef); } } } // Flag to indicate if applet is targeted for JDK 1.1. private boolean jdk11Applet = false; // Flag to indicate if applet is targeted for JDK 1.2. private boolean jdk12Applet = false; /** * Determine JDK level of an applet. */ private void findAppletJDKLevel(Applet applet) { // To determine the JDK level of an applet, the // most reliable way is to check the major version // of the applet class file. // synchronized on applet class object, so calling from // different instances of the same applet will be // serialized. Class appletClass = applet.getClass(); synchronized(appletClass) { // Determine if the JDK level of an applet has been // checked before. Boolean jdk11Target = (Boolean) loader.isJDK11Target(appletClass); Boolean jdk12Target = (Boolean) loader.isJDK12Target(appletClass); // if applet JDK level has been checked before, retrieve // value and return. if (jdk11Target != null || jdk12Target != null) { jdk11Applet = (jdk11Target == null) ? false : jdk11Target.booleanValue(); jdk12Applet = (jdk12Target == null) ? false : jdk12Target.booleanValue(); return; } String name = appletClass.getName(); // first convert any '.' to '/' name = name.replace('.', '/'); // append .class final String resourceName = name + ".class"; InputStream is = null; byte[] classHeader = new byte[8]; try { is = (InputStream) java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public Object run() { return loader.getResourceAsStream(resourceName); } }); // Read the first 8 bytes of the class file int byteRead = is.read(classHeader, 0, 8); is.close(); // return if the header is not read in entirely // for some reasons. if (byteRead != 8) return; } catch (IOException e) { return; } // Check major version in class file header int major_version = readShort(classHeader, 6); // Major version in class file is as follows: // 45 - JDK 1.1 // 46 - JDK 1.2 // 47 - JDK 1.3 // 48 - JDK 1.4 // 49 - JDK 1.5 if (major_version < 46) jdk11Applet = true; else if (major_version == 46) jdk12Applet = true; // Store applet JDK level in AppContext for later lookup, // e.g. page switch. loader.setJDK11Target(appletClass, jdk11Applet); loader.setJDK12Target(appletClass, jdk12Applet); } } /** * Return true if applet is targeted to JDK 1.1. */ protected boolean isJDK11Applet() { return jdk11Applet; } /** * Return true if applet is targeted to JDK1.2. */ protected boolean isJDK12Applet() { return jdk12Applet; } /** * Read short from byte array. */ private int readShort(byte[] b, int off) { int hi = readByte(b[off]); int lo = readByte(b[off + 1]); return (hi << 8) | lo; } private int readByte(byte b) { return ((int)b) & 0xFF; } private static AppletMessageHandler amh = new AppletMessageHandler("appletpanel"); }