mirror of
https://git.freebsd.org/ports.git
synced 2025-06-06 21:30:31 -04:00
243 lines
7.1 KiB
Java
243 lines
7.1 KiB
Java
$FreeBSD$
|
|
|
|
--- ../../deploy/src/plugin/src/share/classes/sun/plugin/javascript/JSClassLoader.java 1 Jan 1970 00:00:00 -0000
|
|
+++ ../../deploy/src/plugin/src/share/classes/sun/plugin/javascript/JSClassLoader.java 3 Dec 2004 03:56:58 -0000 1.1
|
|
@@ -0,0 +1,238 @@
|
|
+/*
|
|
+ * @(#)JSClassLoader.java 1.1 04/06/20
|
|
+ *
|
|
+ * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
|
|
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
|
+ */
|
|
+
|
|
+package sun.plugin.javascript;
|
|
+
|
|
+import java.security.AllPermission;
|
|
+import java.security.AccessController;
|
|
+import java.security.PermissionCollection;
|
|
+import java.security.SecureClassLoader;
|
|
+import java.security.PrivilegedExceptionAction;
|
|
+import java.security.CodeSource;
|
|
+import java.io.InputStream;
|
|
+import java.io.BufferedInputStream;
|
|
+import java.io.IOException;
|
|
+import java.net.URL;
|
|
+import java.net.URLConnection;
|
|
+import java.net.HttpURLConnection;
|
|
+import java.lang.reflect.Method;
|
|
+import java.lang.reflect.InvocationTargetException;
|
|
+import java.lang.reflect.AccessibleObject;
|
|
+import sun.net.www.ParseUtil;
|
|
+import sun.security.util.SecurityConstants;
|
|
+
|
|
+/*
|
|
+ * Create a trampoline class for JavaScript to Java
|
|
+ * method invocations.
|
|
+ *
|
|
+ */
|
|
+public final class JSClassLoader extends SecureClassLoader {
|
|
+ private static String JS_PROXY_PKG = "sun.plugin.javascript.invoke.";
|
|
+ private static String TRAMPOLINE = JS_PROXY_PKG + "JSInvoke";
|
|
+ private static Method bounce;
|
|
+
|
|
+ /*
|
|
+ * Bounce through the trampoline.
|
|
+ */
|
|
+ public static Object invoke(Method m, Object obj, Object[] params)
|
|
+ throws Exception {
|
|
+ try {
|
|
+ return bounce().invoke(null, new Object[] {m, obj, params});
|
|
+ } catch (InvocationTargetException ie) {
|
|
+ Throwable t = ie.getCause();
|
|
+
|
|
+ if (t instanceof InvocationTargetException) {
|
|
+ throw (InvocationTargetException)t;
|
|
+ } else {
|
|
+ throw ie;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Check the package access permission by giving a class
|
|
+ *
|
|
+ * @param clazz: The Class object trying to get access to
|
|
+ *
|
|
+ */
|
|
+ public static void checkPackageAccess(Class clazz) {
|
|
+ String clsname = clazz.getName();
|
|
+ int index = clsname.lastIndexOf(".");
|
|
+ if (index != -1) {
|
|
+ String pkgname = clsname.substring(0, index);
|
|
+ SecurityManager s = System.getSecurityManager();
|
|
+ if (s != null) {
|
|
+ s.checkPackageAccess(pkgname);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static boolean isPackageAccessible(Class clazz) {
|
|
+ try {
|
|
+ checkPackageAccess(clazz);
|
|
+ } catch (SecurityException e) {
|
|
+ return false;
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+
|
|
+ private synchronized static Method bounce() throws Exception {
|
|
+ if (bounce == null) {
|
|
+ bounce = (Method) AccessController.doPrivileged(new PrivilegedExceptionAction() {
|
|
+ public Object run() throws Exception {
|
|
+ Class[] types;
|
|
+ Class t = getTrampoline();
|
|
+ Method b;
|
|
+
|
|
+ types = new Class[] {Method.class, Object.class, Object[].class};
|
|
+ b = t.getDeclaredMethod("invoke", types);
|
|
+ ((AccessibleObject)b).setAccessible(true);
|
|
+ return b;
|
|
+ }
|
|
+ });
|
|
+ }
|
|
+ return bounce;
|
|
+ }
|
|
+
|
|
+ private static Class getTrampoline() {
|
|
+ try {
|
|
+ return Class.forName(TRAMPOLINE, true, new JSClassLoader());
|
|
+ } catch (ClassNotFoundException e) {
|
|
+ }
|
|
+ return null;
|
|
+ }
|
|
+
|
|
+
|
|
+ protected synchronized Class loadClass(String name, boolean resolve)
|
|
+ throws ClassNotFoundException
|
|
+ {
|
|
+ SecurityManager s = System.getSecurityManager();
|
|
+ if (s != null) {
|
|
+ String cname = name.replace('/', '.');
|
|
+ if (cname.startsWith("[")) {
|
|
+ int b = cname.lastIndexOf('[') + 2;
|
|
+ if (b > 1 && b < cname.length()) {
|
|
+ cname = cname.substring(b);
|
|
+ }
|
|
+ }
|
|
+ int i = cname.lastIndexOf('.');
|
|
+ if (i != -1) {
|
|
+ s.checkPackageAccess(cname.substring(0, i));
|
|
+ }
|
|
+ }
|
|
+ // First, check if the class has already been loaded
|
|
+ Class c = findLoadedClass(name);
|
|
+ if (c == null) {
|
|
+ try {
|
|
+ c = findClass(name);
|
|
+ } catch (ClassNotFoundException e) {
|
|
+ // Fall through ...
|
|
+ }
|
|
+ if (c == null) {
|
|
+ c = getParent().loadClass(name);
|
|
+ }
|
|
+ }
|
|
+ if (resolve) {
|
|
+ resolveClass(c);
|
|
+ }
|
|
+ return c;
|
|
+ }
|
|
+
|
|
+
|
|
+ protected Class findClass(final String name)
|
|
+ throws ClassNotFoundException
|
|
+ {
|
|
+ if (!name.startsWith(JS_PROXY_PKG)) {
|
|
+ throw new ClassNotFoundException(name);
|
|
+ }
|
|
+ String path = name.replace('.', '/').concat(".class");
|
|
+ URL res = getResource(path);
|
|
+ if (res != null) {
|
|
+ try {
|
|
+ return defineClass(name, res);
|
|
+ } catch (IOException e) {
|
|
+ throw new ClassNotFoundException(name, e);
|
|
+ }
|
|
+ } else {
|
|
+ throw new ClassNotFoundException(name);
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ /*
|
|
+ * Define the JavaScript proxy classes
|
|
+ */
|
|
+ private Class defineClass(String name, URL url) throws IOException {
|
|
+ byte[] b = getBytes(url);
|
|
+ CodeSource cs = new CodeSource(null, (java.security.cert.Certificate[])null);
|
|
+ if (!name.equals(TRAMPOLINE)) {
|
|
+ throw new IOException("JSClassLoader: bad name " + name);
|
|
+ }
|
|
+ return defineClass(name, b, 0, b.length, cs);
|
|
+ }
|
|
+
|
|
+
|
|
+ /*
|
|
+ * Returns the contents of the specified URL as an array of bytes.
|
|
+ */
|
|
+ private static byte[] getBytes(URL url) throws IOException {
|
|
+ URLConnection uc = url.openConnection();
|
|
+ if (uc instanceof java.net.HttpURLConnection) {
|
|
+ java.net.HttpURLConnection huc = (java.net.HttpURLConnection) uc;
|
|
+ int code = huc.getResponseCode();
|
|
+ if (code >= java.net.HttpURLConnection.HTTP_BAD_REQUEST) {
|
|
+ throw new IOException("open HTTP connection failed.");
|
|
+ }
|
|
+ }
|
|
+ int len = uc.getContentLength();
|
|
+ InputStream in = new BufferedInputStream(uc.getInputStream());
|
|
+
|
|
+ byte[] b;
|
|
+ try {
|
|
+ if (len != -1) {
|
|
+ // Read exactly len bytes from the input stream
|
|
+ b = new byte[len];
|
|
+ while (len > 0) {
|
|
+ int n = in.read(b, b.length - len, len);
|
|
+ if (n == -1) {
|
|
+ throw new IOException("unexpected EOF");
|
|
+ }
|
|
+ len -= n;
|
|
+ }
|
|
+ } else {
|
|
+ b = new byte[8192];
|
|
+ int total = 0;
|
|
+ while ((len = in.read(b, total, b.length - total)) != -1) {
|
|
+ total += len;
|
|
+ if (total >= b.length) {
|
|
+ byte[] tmp = new byte[total * 2];
|
|
+ System.arraycopy(b, 0, tmp, 0, total);
|
|
+ b = tmp;
|
|
+ }
|
|
+ }
|
|
+ // Trim array to correct size, if necessary
|
|
+ if (total != b.length) {
|
|
+ byte[] tmp = new byte[total];
|
|
+ System.arraycopy(b, 0, tmp, 0, total);
|
|
+ b = tmp;
|
|
+ }
|
|
+ }
|
|
+ } finally {
|
|
+ in.close();
|
|
+ }
|
|
+ return b;
|
|
+ }
|
|
+
|
|
+
|
|
+ protected PermissionCollection getPermissions(CodeSource codesource)
|
|
+ {
|
|
+ PermissionCollection perms = super.getPermissions(codesource);
|
|
+ perms.add(new AllPermission());
|
|
+ return perms;
|
|
+ }
|
|
+}
|