aboutsummaryrefslogtreecommitdiffstats
path: root/plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java
diff options
context:
space:
mode:
authorandrew <devnull@localhost>2010-10-19 17:55:59 +0100
committerandrew <devnull@localhost>2010-10-19 17:55:59 +0100
commit7603e948d7a0a7eb2e72358cb4a40ae6779f95da (patch)
treec6441f7d14eafe8119d890cddd09b05b8f88c52a /plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java
Initial import from IcedTea6.
2010-10-19 Andrew John Hughes <[email protected]> * .hgignore, * Makefile.am, * acinclude.m4, * autogen.sh, * configure.ac, * extra/net/sourceforge/jnlp/about/HTMLPanel.java, * extra/net/sourceforge/jnlp/about/Main.java, * extra/net/sourceforge/jnlp/about/resources/about.html, * extra/net/sourceforge/jnlp/about/resources/applications.html, * extra/net/sourceforge/jnlp/about/resources/notes.html, * javac.in, * javaws.desktop: Imported from IcedTea6. * launcher/java.c, * launcher/java.h, * launcher/java_md.c, * launcher/java_md.h, * launcher/jli_util.h, * launcher/jni.h, * launcher/jvm.h, * launcher/jvm_md.h, * launcher/manifest_info.h, * launcher/splashscreen.h, * launcher/splashscreen_stubs.c, * launcher/version_comp.h, * launcher/wildcard.h: Imported from OpenJDK. * netx/javaws.1, * netx/javax/jnlp/BasicService.java, * netx/javax/jnlp/ClipboardService.java, * netx/javax/jnlp/DownloadService.java, * netx/javax/jnlp/DownloadServiceListener.java, * netx/javax/jnlp/ExtendedService.java, * netx/javax/jnlp/ExtensionInstallerService.java, * netx/javax/jnlp/FileContents.java, * netx/javax/jnlp/FileOpenService.java, * netx/javax/jnlp/FileSaveService.java, * netx/javax/jnlp/JNLPRandomAccessFile.java, * netx/javax/jnlp/PersistenceService.java, * netx/javax/jnlp/PrintService.java, * netx/javax/jnlp/ServiceManager.java, * netx/javax/jnlp/ServiceManagerStub.java, * netx/javax/jnlp/SingleInstanceListener.java, * netx/javax/jnlp/SingleInstanceService.java, * netx/javax/jnlp/UnavailableServiceException.java, * netx/net/sourceforge/jnlp/AppletDesc.java, * netx/net/sourceforge/jnlp/ApplicationDesc.java, * netx/net/sourceforge/jnlp/AssociationDesc.java, * netx/net/sourceforge/jnlp/ComponentDesc.java, * netx/net/sourceforge/jnlp/DefaultLaunchHandler.java, * netx/net/sourceforge/jnlp/ExtensionDesc.java, * netx/net/sourceforge/jnlp/IconDesc.java, * netx/net/sourceforge/jnlp/InformationDesc.java, * netx/net/sourceforge/jnlp/InstallerDesc.java, * netx/net/sourceforge/jnlp/JARDesc.java, * netx/net/sourceforge/jnlp/JNLPFile.java, * netx/net/sourceforge/jnlp/JNLPSplashScreen.java, * netx/net/sourceforge/jnlp/JREDesc.java, * netx/net/sourceforge/jnlp/LaunchException.java, * netx/net/sourceforge/jnlp/LaunchHandler.java, * netx/net/sourceforge/jnlp/Launcher.java, * netx/net/sourceforge/jnlp/MenuDesc.java, * netx/net/sourceforge/jnlp/NetxPanel.java, * netx/net/sourceforge/jnlp/Node.java, * netx/net/sourceforge/jnlp/PackageDesc.java, * netx/net/sourceforge/jnlp/ParseException.java, * netx/net/sourceforge/jnlp/Parser.java, * netx/net/sourceforge/jnlp/PluginBridge.java, * netx/net/sourceforge/jnlp/PropertyDesc.java, * netx/net/sourceforge/jnlp/RelatedContentDesc.java, * netx/net/sourceforge/jnlp/ResourcesDesc.java, * netx/net/sourceforge/jnlp/SecurityDesc.java, * netx/net/sourceforge/jnlp/ShortcutDesc.java, * netx/net/sourceforge/jnlp/StreamEater.java, * netx/net/sourceforge/jnlp/UpdateDesc.java, * netx/net/sourceforge/jnlp/Version.java, * netx/net/sourceforge/jnlp/cache/CacheEntry.java, * netx/net/sourceforge/jnlp/cache/CacheUtil.java, * netx/net/sourceforge/jnlp/cache/DefaultDownloadIndicator.java, * netx/net/sourceforge/jnlp/cache/DownloadIndicator.java, * netx/net/sourceforge/jnlp/cache/Resource.java, * netx/net/sourceforge/jnlp/cache/ResourceTracker.java, * netx/net/sourceforge/jnlp/cache/UpdatePolicy.java, * netx/net/sourceforge/jnlp/cache/package.html, * netx/net/sourceforge/jnlp/event/ApplicationEvent.java, * netx/net/sourceforge/jnlp/event/ApplicationListener.java, * netx/net/sourceforge/jnlp/event/DownloadEvent.java, * netx/net/sourceforge/jnlp/event/DownloadListener.java, * netx/net/sourceforge/jnlp/event/package.html, * netx/net/sourceforge/jnlp/package.html, * netx/net/sourceforge/jnlp/resources/Manifest.mf, * netx/net/sourceforge/jnlp/resources/Messages.properties, * netx/net/sourceforge/jnlp/resources/about.jnlp, * netx/net/sourceforge/jnlp/resources/default.jnlp, * netx/net/sourceforge/jnlp/runtime/AppThreadGroup.java, * netx/net/sourceforge/jnlp/runtime/AppletAudioClip.java, * netx/net/sourceforge/jnlp/runtime/AppletEnvironment.java, * netx/net/sourceforge/jnlp/runtime/AppletInstance.java, * netx/net/sourceforge/jnlp/runtime/ApplicationInstance.java, * netx/net/sourceforge/jnlp/runtime/Boot.java, * netx/net/sourceforge/jnlp/runtime/Boot13.java, * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java, * netx/net/sourceforge/jnlp/runtime/JNLPPolicy.java, * netx/net/sourceforge/jnlp/runtime/JNLPRuntime.java, * netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java, * netx/net/sourceforge/jnlp/runtime/package.html, * netx/net/sourceforge/jnlp/security/AccessWarningPane.java, * netx/net/sourceforge/jnlp/security/AppletWarningPane.java, * netx/net/sourceforge/jnlp/security/CertVerifier.java, * netx/net/sourceforge/jnlp/security/CertWarningPane.java, * netx/net/sourceforge/jnlp/security/CertsInfoPane.java, * netx/net/sourceforge/jnlp/security/HttpsCertVerifier.java, * netx/net/sourceforge/jnlp/security/MoreInfoPane.java, * netx/net/sourceforge/jnlp/security/NotAllSignedWarningPane.java, * netx/net/sourceforge/jnlp/security/SecurityDialogPanel.java, * netx/net/sourceforge/jnlp/security/SecurityUtil.java, * netx/net/sourceforge/jnlp/security/SecurityWarningDialog.java, * netx/net/sourceforge/jnlp/security/SingleCertInfoPane.java, * netx/net/sourceforge/jnlp/security/VariableX509TrustManager.java, * netx/net/sourceforge/jnlp/security/viewer/CertificatePane.java, * netx/net/sourceforge/jnlp/security/viewer/CertificateViewer.java, * netx/net/sourceforge/jnlp/services/ExtendedSingleInstanceService.java, * netx/net/sourceforge/jnlp/services/InstanceExistsException.java, * netx/net/sourceforge/jnlp/services/ServiceUtil.java, * netx/net/sourceforge/jnlp/services/SingleInstanceLock.java, * netx/net/sourceforge/jnlp/services/XBasicService.java, * netx/net/sourceforge/jnlp/services/XClipboardService.java, * netx/net/sourceforge/jnlp/services/XDownloadService.java, * netx/net/sourceforge/jnlp/services/XExtendedService.java, * netx/net/sourceforge/jnlp/services/XExtensionInstallerService.java, * netx/net/sourceforge/jnlp/services/XFileContents.java, * netx/net/sourceforge/jnlp/services/XFileOpenService.java, * netx/net/sourceforge/jnlp/services/XFileSaveService.java, * netx/net/sourceforge/jnlp/services/XJNLPRandomAccessFile.java, * netx/net/sourceforge/jnlp/services/XPersistenceService.java, * netx/net/sourceforge/jnlp/services/XPrintService.java, * netx/net/sourceforge/jnlp/services/XServiceManagerStub.java, * netx/net/sourceforge/jnlp/services/XSingleInstanceService.java, * netx/net/sourceforge/jnlp/services/package.html, * netx/net/sourceforge/jnlp/tools/CharacterEncoder.java, * netx/net/sourceforge/jnlp/tools/HexDumpEncoder.java, * netx/net/sourceforge/jnlp/tools/JarRunner.java, * netx/net/sourceforge/jnlp/tools/JarSigner.java, * netx/net/sourceforge/jnlp/tools/JarSignerResources.java, * netx/net/sourceforge/jnlp/tools/KeyStoreUtil.java, * netx/net/sourceforge/jnlp/tools/KeyTool.java, * netx/net/sourceforge/jnlp/util/FileUtils.java, * netx/net/sourceforge/jnlp/util/PropertiesFile.java, * netx/net/sourceforge/jnlp/util/Reflect.java, * netx/net/sourceforge/jnlp/util/WeakList.java, * netx/net/sourceforge/jnlp/util/XDesktopEntry.java, * netx/net/sourceforge/nanoxml/XMLElement.java, * netx/net/sourceforge/nanoxml/XMLParseException.java, * plugin/icedteanp/IcedTeaJavaRequestProcessor.cc, * plugin/icedteanp/IcedTeaJavaRequestProcessor.h, * plugin/icedteanp/IcedTeaNPPlugin.cc, * plugin/icedteanp/IcedTeaNPPlugin.h, * plugin/icedteanp/IcedTeaPluginRequestProcessor.cc, * plugin/icedteanp/IcedTeaPluginRequestProcessor.h, * plugin/icedteanp/IcedTeaPluginUtils.cc, * plugin/icedteanp/IcedTeaPluginUtils.h, * plugin/icedteanp/IcedTeaRunnable.cc, * plugin/icedteanp/IcedTeaRunnable.h, * plugin/icedteanp/IcedTeaScriptablePluginObject.cc, * plugin/icedteanp/IcedTeaScriptablePluginObject.h, * plugin/icedteanp/java/netscape/javascript/JSException.java, * plugin/icedteanp/java/netscape/javascript/JSObject.java, * plugin/icedteanp/java/netscape/javascript/JSObjectCreatePermission.java, * plugin/icedteanp/java/netscape/javascript/JSProxy.java, * plugin/icedteanp/java/netscape/javascript/JSRunnable.java, * plugin/icedteanp/java/netscape/javascript/JSUtil.java, * plugin/icedteanp/java/netscape/security/ForbiddenTargetException.java, * plugin/icedteanp/java/sun/applet/AppletSecurityContextManager.java, * plugin/icedteanp/java/sun/applet/GetMemberPluginCallRequest.java, * plugin/icedteanp/java/sun/applet/GetWindowPluginCallRequest.java, * plugin/icedteanp/java/sun/applet/JavaConsole.java, * plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java, * plugin/icedteanp/java/sun/applet/PasswordAuthenticationDialog.java, * plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java, * plugin/icedteanp/java/sun/applet/PluginAppletViewer.java, * plugin/icedteanp/java/sun/applet/PluginCallRequest.java, * plugin/icedteanp/java/sun/applet/PluginCallRequestFactory.java, * plugin/icedteanp/java/sun/applet/PluginClassLoader.java, * plugin/icedteanp/java/sun/applet/PluginCookieInfoRequest.java, * plugin/icedteanp/java/sun/applet/PluginCookieManager.java, * plugin/icedteanp/java/sun/applet/PluginDebug.java, * plugin/icedteanp/java/sun/applet/PluginException.java, * plugin/icedteanp/java/sun/applet/PluginMain.java, * plugin/icedteanp/java/sun/applet/PluginMessageConsumer.java, * plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java, * plugin/icedteanp/java/sun/applet/PluginObjectStore.java, * plugin/icedteanp/java/sun/applet/PluginProxyInfoRequest.java, * plugin/icedteanp/java/sun/applet/PluginProxySelector.java, * plugin/icedteanp/java/sun/applet/PluginStreamHandler.java, * plugin/icedteanp/java/sun/applet/RequestQueue.java, * plugin/icedteanp/java/sun/applet/TestEnv.java, * plugin/icedteanp/java/sun/applet/VoidPluginCallRequest.java, * plugin/tests/LiveConnect/DummyObject.java, * plugin/tests/LiveConnect/OverloadTestHelper1.java, * plugin/tests/LiveConnect/OverloadTestHelper2.java, * plugin/tests/LiveConnect/OverloadTestHelper3.java, * plugin/tests/LiveConnect/PluginTest.java, * plugin/tests/LiveConnect/build, * plugin/tests/LiveConnect/common.js, * plugin/tests/LiveConnect/index.html, * plugin/tests/LiveConnect/jjs_eval_test.js, * plugin/tests/LiveConnect/jjs_func_parameters_tests.js, * plugin/tests/LiveConnect/jjs_func_rettype_tests.js, * plugin/tests/LiveConnect/jjs_get_tests.js, * plugin/tests/LiveConnect/jjs_set_tests.js, * plugin/tests/LiveConnect/jsj_func_overload_tests.js, * plugin/tests/LiveConnect/jsj_func_parameters_tests.js, * plugin/tests/LiveConnect/jsj_func_rettype_tests.js, * plugin/tests/LiveConnect/jsj_get_tests.js, * plugin/tests/LiveConnect/jsj_set_tests.js, * plugin/tests/LiveConnect/jsj_type_casting_tests.js, * plugin/tests/LiveConnect/jsj_type_conversion_tests.js: Initial import from IcedTea6. * AUTHORS, * COPYING * INSTALL, * NEWS, * README: New documentation.
Diffstat (limited to 'plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java')
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java1505
1 files changed, 1505 insertions, 0 deletions
diff --git a/plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java b/plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java
new file mode 100644
index 0000000..bef2bd8
--- /dev/null
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java
@@ -0,0 +1,1505 @@
+/* PluginAppletSecurityContext -- execute plugin JNI messages
+ Copyright (C) 2008 Red Hat
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+IcedTea 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 for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package sun.applet;
+
+import java.io.File;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.AccessControlContext;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.AllPermission;
+import java.security.BasicPermission;
+import java.security.CodeSource;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.text.html.HTMLDocument.HTMLReader.IsindexAction;
+
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import netscape.javascript.JSObjectCreatePermission;
+
+
+
+class Signature {
+ private String signature;
+ private int currentIndex;
+ private List<Class> typeList;
+ private static final char ARRAY = '[';
+ private static final char OBJECT = 'L';
+ private static final char SIGNATURE_ENDCLASS = ';';
+ private static final char SIGNATURE_FUNC = '(';
+ private static final char SIGNATURE_ENDFUNC = ')';
+ private static final char VOID = 'V';
+ private static final char BOOLEAN = 'Z';
+ private static final char BYTE = 'B';
+ private static final char CHARACTER = 'C';
+ private static final char SHORT = 'S';
+ private static final char INTEGER = 'I';
+ private static final char LONG = 'J';
+ private static final char FLOAT = 'F';
+ private static final char DOUBLE = 'D';
+
+ private String nextTypeName() {
+ char key = signature.charAt(currentIndex++);
+
+ switch (key) {
+ case ARRAY:
+ return nextTypeName() + "[]";
+
+ case OBJECT:
+ int endClass = signature.indexOf(SIGNATURE_ENDCLASS, currentIndex);
+ String retVal = signature.substring(currentIndex, endClass);
+ retVal = retVal.replace('/', '.');
+ currentIndex = endClass + 1;
+ return retVal;
+
+ // FIXME: generated bytecode with classes named after
+ // primitives will not work in this scheme -- those
+ // classes will be incorrectly treated as primitive
+ // types.
+ case VOID:
+ return "void";
+ case BOOLEAN:
+ return "boolean";
+ case BYTE:
+ return "byte";
+ case CHARACTER:
+ return "char";
+ case SHORT:
+ return "short";
+ case INTEGER:
+ return "int";
+ case LONG:
+ return "long";
+ case FLOAT:
+ return "float";
+ case DOUBLE:
+ return "double";
+
+ case SIGNATURE_ENDFUNC:
+ return null;
+
+ case SIGNATURE_FUNC:
+ return nextTypeName();
+
+ default:
+ throw new IllegalArgumentException(
+ "Invalid JNI signature character '" + key + "'");
+ }
+ }
+
+ public Signature(String signature, ClassLoader cl) {
+ this.signature = signature;
+ currentIndex = 0;
+ typeList = new ArrayList<Class>(10);
+
+ String elem;
+ while (currentIndex < signature.length()) {
+ elem = nextTypeName();
+
+ if (elem == null) // end of signature
+ continue;
+
+ // System.out.println ("NEXT TYPE: " + elem);
+ Class primitive = primitiveNameToType(elem);
+ if (primitive != null)
+ typeList.add(primitive);
+ else {
+ // System.out.println ("HERE1");
+ int dimsize = 0;
+ int n = elem.indexOf('[');
+ if (n != -1) {
+ // System.out.println ("HERE2");
+ String arrayType = elem.substring(0, n);
+ dimsize++;
+ n = elem.indexOf('[', n + 1);
+ // System.out.println ("HERE2.5");
+ while (n != -1) {
+ dimsize++;
+ n = elem.indexOf('[', n + 1);
+ // System.out.println ("HERE2.8");
+ }
+ int[] dims = new int[dimsize];
+ primitive = primitiveNameToType(arrayType);
+ // System.out.println ("HERE3");
+ if (primitive != null) {
+ typeList.add(Array.newInstance(primitive, dims)
+ .getClass());
+ // System.out.println ("HERE4");
+ } else
+ typeList.add(Array.newInstance(
+ getClass(arrayType, cl), dims).getClass());
+ } else {
+ typeList.add(getClass(elem, cl));
+ }
+ }
+ }
+ if (signature.length() < 2) {
+ throw new IllegalArgumentException("Invalid JNI signature '"
+ + signature + "'");
+ }
+ }
+
+ public static Class getClass(String name, ClassLoader cl) {
+
+ Class c = null;
+
+ try {
+ c = Class.forName(name);
+ } catch (ClassNotFoundException cnfe) {
+
+ PluginDebug.debug("Class " + name + " not found in primordial loader. Looking in " + cl);
+ try {
+ c = cl.loadClass(name);
+ } catch (ClassNotFoundException e) {
+ throw (new RuntimeException(new ClassNotFoundException("Unable to find class " + name)));
+ }
+ }
+
+ return c;
+ }
+
+ public static Class primitiveNameToType(String name) {
+ if (name.equals("void"))
+ return Void.TYPE;
+ else if (name.equals("boolean"))
+ return Boolean.TYPE;
+ else if (name.equals("byte"))
+ return Byte.TYPE;
+ else if (name.equals("char"))
+ return Character.TYPE;
+ else if (name.equals("short"))
+ return Short.TYPE;
+ else if (name.equals("int"))
+ return Integer.TYPE;
+ else if (name.equals("long"))
+ return Long.TYPE;
+ else if (name.equals("float"))
+ return Float.TYPE;
+ else if (name.equals("double"))
+ return Double.TYPE;
+ else
+ return null;
+ }
+
+ public Class[] getClassArray() {
+ return typeList.subList(0, typeList.size()).toArray(new Class[] {});
+ }
+}
+
+public class PluginAppletSecurityContext {
+
+ private static Hashtable<ClassLoader, URL> classLoaders = new Hashtable<ClassLoader, URL>();
+ private static Hashtable<Integer, ClassLoader> instanceClassLoaders = new Hashtable<Integer, ClassLoader>();
+
+ // FIXME: make private
+ public PluginObjectStore store = new PluginObjectStore();
+ private Throwable throwable = null;
+ private ClassLoader liveconnectLoader = ClassLoader.getSystemClassLoader();
+ int identifier = 0;
+
+ public static PluginStreamHandler streamhandler;
+
+ long startTime = 0;
+
+ public PluginAppletSecurityContext(int identifier) {
+ this.identifier = identifier;
+
+ // also, override the basedir, use a different one for the plugin
+ File f = new File(System.getProperty("user.home") + "/.icedteaplugin/");
+ f.mkdir();
+ JNLPRuntime.setBaseDir(f);
+
+ // We need a security manager.. and since there is a good chance that
+ // an applet will be loaded at some point, we should make it the SM
+ // that JNLPRuntime will try to install
+ if (System.getSecurityManager() == null) {
+ JNLPRuntime.initialize(/* isApplication */ false);
+ }
+
+ JNLPRuntime.disableExit();
+
+ URL u = null;
+ try {
+ u = new URL("file://");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+
+ this.classLoaders.put(liveconnectLoader, u);
+ }
+
+ private static <V> V parseCall(String s, ClassLoader cl, Class<V> c) {
+ if (c == Integer.class)
+ return (V) new Integer(s);
+ else if (c == String.class)
+ return (V) new String(s);
+ else if (c == Signature.class)
+ return (V) new Signature(s, cl);
+ else
+ throw new RuntimeException("Unexpected call value.");
+ }
+
+ private Object parseArgs(String s, Class c) {
+ if (c == Boolean.TYPE || c == Boolean.class)
+ return new Boolean(s);
+ else if (c == Byte.TYPE || c == Byte.class)
+ return new Byte(s);
+ else if (c == Character.TYPE || c == Character.class) {
+ String[] bytes = s.split("_");
+ int low = Integer.parseInt(bytes[0]);
+ int high = Integer.parseInt(bytes[1]);
+ int full = ((high << 8) & 0x0ff00) | (low & 0x0ff);
+ return new Character((char) full);
+ } else if (c == Short.TYPE || c == Short.class)
+ return new Short(s);
+ else if (c == Integer.TYPE || c == Integer.class)
+ return new Integer(s);
+ else if (c == Long.TYPE || c == Long.class)
+ return new Long(s);
+ else if (c == Float.TYPE || c == Float.class)
+ return new Float(s);
+ else if (c == Double.TYPE || c == Double.class)
+ return new Double(s);
+ else
+ return store.getObject(new Integer(s));
+ }
+
+ public void associateSrc(ClassLoader cl, URL src) {
+ PluginDebug.debug("Associating " + cl + " with " + src);
+ this.classLoaders.put(cl, src);
+ }
+
+ public void associateInstance(Integer i, ClassLoader cl) {
+ PluginDebug.debug("Associating " + cl + " with instance " + i);
+ this.instanceClassLoaders.put(i, cl);
+ }
+
+ public static void setStreamhandler(PluginStreamHandler sh) {
+ streamhandler = sh;
+ }
+
+ public static Map<String, String> getLoaderInfo() {
+ Hashtable<String, String> map = new Hashtable<String, String>();
+
+ for (ClassLoader loader : PluginAppletSecurityContext.classLoaders.keySet()) {
+ map.put(loader.getClass().getName(), classLoaders.get(loader).toString());
+ }
+
+ return map;
+ }
+
+ public void handleMessage(int reference, String src, AccessControlContext callContext, String message) {
+
+ startTime = new java.util.Date().getTime();
+
+ try {
+ if (message.startsWith("FindClass")) {
+ ClassLoader cl = null;
+ Class c = null;
+ cl = liveconnectLoader;
+ String[] args = message.split(" ");
+ Integer instance = new Integer(args[1]);
+ String className = args[2].replace('/', '.');
+ PluginDebug.debug("Searching for class " + className + " in " + cl);
+
+ try {
+ c = cl.loadClass(className);
+ store.reference(c);
+ write(reference, "FindClass " + store.getIdentifier(c));
+ } catch (ClassNotFoundException cnfe) {
+
+ cl = this.instanceClassLoaders.get(instance);
+ PluginDebug.debug("Not found. Looking in " + cl);
+
+ if (instance != 0 && cl != null) {
+ try {
+ c = cl.loadClass(className);
+ store.reference(c);
+ write(reference, "FindClass " + store.getIdentifier(c));
+ } catch (ClassNotFoundException cnfe2) {
+ write(reference, "FindClass 0");
+ }
+ } else {
+ write(reference, "FindClass 0");
+ }
+ }
+
+ } else if (message.startsWith("GetStaticMethodID")
+ || message.startsWith("GetMethodID")) {
+ String[] args = message.split(" ");
+ Integer classID = parseCall(args[1], null, Integer.class);
+ String methodName = parseCall(args[2], null, String.class);
+ Signature signature = parseCall(args[3], ((Class) store.getObject(classID)).getClassLoader(), Signature.class);
+ Object[] a = signature.getClassArray();
+
+ Class c;
+
+ if (message.startsWith("GetStaticMethodID") ||
+ methodName.equals("<init>") ||
+ methodName.equals("<clinit>"))
+ c = (Class) store.getObject(classID);
+ else
+ c = store.getObject(classID).getClass();
+
+ Method m = null;
+ Constructor cs = null;
+ Object o = null;
+ if (methodName.equals("<init>")
+ || methodName.equals("<clinit>")) {
+ o = cs = c.getConstructor(signature.getClassArray());
+ store.reference(cs);
+ } else {
+ o = m = c.getMethod(methodName, signature.getClassArray());
+ store.reference(m);
+ }
+ PluginDebug.debug(o + " has id " + store.getIdentifier(o));
+ write(reference, args[0] + " " + store.getIdentifier(o));
+ } else if (message.startsWith("GetStaticFieldID")
+ || message.startsWith("GetFieldID")) {
+ String[] args = message.split(" ");
+ Integer classID = parseCall(args[1], null, Integer.class);
+ Integer fieldID = parseCall(args[2], null, Integer.class);
+ String fieldName = (String) store.getObject(fieldID);
+
+ Class c = (Class) store.getObject(classID);
+
+ PluginDebug.debug("GetStaticFieldID/GetFieldID got class=" + c.getName());
+
+ Field f = null;
+ f = c.getField(fieldName);
+
+ store.reference(f);
+
+ write(reference, "GetStaticFieldID " + store.getIdentifier(f));
+ } else if (message.startsWith("GetStaticField")) {
+ String[] args = message.split(" ");
+ String type = parseCall(args[1], null, String.class);
+ Integer classID = parseCall(args[1], null, Integer.class);
+ Integer fieldID = parseCall(args[2], null, Integer.class);
+
+ final Class c = (Class) store.getObject(classID);
+ final Field f = (Field) store.getObject(fieldID);
+
+ AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+ checkPermission(src, c, acc);
+
+ Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
+ public Object run() {
+ try {
+ return f.get(c);
+ } catch (Throwable t) {
+ return t;
+ }
+ }
+ }, acc);
+
+ if (ret instanceof Throwable)
+ throw (Throwable) ret;
+
+ if (ret == null) {
+ write(reference, "GetStaticField literalreturn null");
+ } else if (f.getType() == Boolean.TYPE
+ || f.getType() == Byte.TYPE
+ || f.getType() == Short.TYPE
+ || f.getType() == Integer.TYPE
+ || f.getType() == Long.TYPE) {
+ write(reference, "GetStaticField literalreturn " + ret);
+ } else if (f.getType() == Float.TYPE
+ || f.getType() == Double.TYPE) {
+ write(reference, "GetStaticField literalreturn " + String.format("%308.308e", ret));
+ } else if (f.getType() == Character.TYPE) {
+ write(reference, "GetStaticField literalreturn " + (int) (Character) ret);
+ } else {
+ // Track returned object.
+ store.reference(ret);
+ write(reference, "GetStaticField " + store.getIdentifier(ret));
+ }
+ } else if (message.startsWith("GetValue")) {
+ String[] args = message.split(" ");
+ Integer index = parseCall(args[1], null, Integer.class);
+
+ Object ret = store.getObject(index);
+
+ if (ret == null) {
+ write(reference, "GetValue literalreturn null");
+ } else if (ret.getClass() == Boolean.TYPE
+ || ret.getClass() == Boolean.class
+ || ret.getClass() == Byte.TYPE
+ || ret.getClass() == Byte.class
+ || ret.getClass() == Short.TYPE
+ || ret.getClass() == Short.class
+ || ret.getClass() == Integer.TYPE
+ || ret.getClass() == Integer.class
+ || ret.getClass() == Long.TYPE
+ || ret.getClass() == Long.class) {
+ write(reference, "GetValue literalreturn " + ret);
+ } else if (ret.getClass() == Float.TYPE
+ || ret.getClass() == Float.class
+ || ret.getClass() == Double.TYPE
+ || ret.getClass() == Double.class) {
+ write(reference, "GetValue literalreturn " + String.format("%308.308e", ret));
+ } else if (ret.getClass() == Character.TYPE
+ || ret.getClass() == Character.class) {
+ write(reference, "GetValue literalreturn " + (int) (Character) ret);
+ } else {
+ // Track returned object.
+ store.reference(ret);
+ write(reference, "GetValue " + store.getIdentifier(ret));
+ }
+ } else if (message.startsWith("SetStaticField") ||
+ message.startsWith("SetField")) {
+ String[] args = message.split(" ");
+ Integer classOrObjectID = parseCall(args[1], null, Integer.class);
+ Integer fieldID = parseCall(args[2], null, Integer.class);
+ Object value = store.getObject(parseCall(args[3], null, Integer.class));
+
+ final Object o = store.getObject(classOrObjectID);
+ final Field f = (Field) store.getObject(fieldID);
+
+ final Object fValue = MethodOverloadResolver.getCostAndCastedObject(value, f.getType())[1];
+
+ AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+ checkPermission(src,
+ message.startsWith("SetStaticField") ? (Class) o : o.getClass(),
+ acc);
+
+ Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
+ public Object run() {
+ try {
+ f.set(o, fValue);
+ } catch (Throwable t) {
+ return t;
+ }
+
+ return null;
+ }
+ }, acc);
+
+ if (ret instanceof Throwable)
+ throw (Throwable) ret;
+
+ write(reference, "SetField");
+ } else if (message.startsWith("GetObjectArrayElement")) {
+ String[] args = message.split(" ");
+ Integer arrayID = parseCall(args[1], null, Integer.class);
+ Integer index = parseCall(args[2], null, Integer.class);
+
+ Object ret = Array.get(store.getObject(arrayID), index);
+ Class retClass = store.getObject(arrayID).getClass().getComponentType(); // prevent auto-boxing influence
+
+ if (ret == null) {
+ write(reference, "GetObjectArrayElement literalreturn null");
+ } else if (retClass == Boolean.TYPE
+ || retClass == Byte.TYPE
+ || retClass == Short.TYPE
+ || retClass== Integer.TYPE
+ || retClass== Long.TYPE) {
+ write(reference, "GetObjectArrayElement literalreturn " + ret);
+ } else if (retClass == Float.TYPE
+ || retClass == Double.TYPE) {
+ write(reference, "GetObjectArrayElement literalreturn " + String.format("%308.308e", ret));
+ } else if (retClass == Character.TYPE) {
+ write(reference, "GetObjectArrayElement literalreturn " + (int) (Character) ret);
+ } else {
+ // Track returned object.
+ store.reference(ret);
+ write(reference, "GetObjectArrayElement " + store.getIdentifier(ret));
+ }
+
+ } else if (message.startsWith("SetObjectArrayElement")) {
+ String[] args = message.split(" ");
+ Integer arrayID = parseCall(args[1], null, Integer.class);
+ Integer index = parseCall(args[2], null, Integer.class);
+ Integer objectID = parseCall(args[3], null, Integer.class);
+
+ Object value = store.getObject(objectID);
+
+ // Cast the object to appropriate type before insertion
+ value = MethodOverloadResolver.getCostAndCastedObject(value, store.getObject(arrayID).getClass().getComponentType())[1];
+
+ //if (value == null &&
+ // store.getObject(arrayID).getClass().getComponentType().isPrimitive()) {
+ // value = 0;
+ //}
+
+ Array.set(store.getObject(arrayID), index, value);
+
+ write(reference, "SetObjectArrayElement");
+ } else if (message.startsWith("GetArrayLength")) {
+ String[] args = message.split(" ");
+ Integer arrayID = parseCall(args[1], null, Integer.class);
+
+ //System.out.println("ARRAYID: " + arrayID);
+ Object o = (Object) store.getObject(arrayID);
+ int len = 0;
+ len = Array.getLength(o);
+ // System.out.println ("Returning array length: " + len);
+
+ // System.out.println ("array length: " + o + " " + len);
+ write(reference, "GetArrayLength " + Array.getLength(o));
+ } else if (message.startsWith("GetField")) {
+ String[] args = message.split(" ");
+ String type = parseCall(args[1], null, String.class);
+ Integer objectID = parseCall(args[1], null, Integer.class);
+ Integer fieldID = parseCall(args[2], null, Integer.class);
+
+ final Object o = (Object) store.getObject(objectID);
+ final Field f = (Field) store.getObject(fieldID);
+
+ AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+ checkPermission(src, o.getClass(), acc);
+
+ Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
+ public Object run() {
+ try {
+ return f.get(o);
+ } catch (Throwable t) {
+ return t;
+ }
+ }
+ }, acc);
+
+ if (ret instanceof Throwable)
+ throw (Throwable) ret;
+
+ if (ret == null) {
+ write(reference, "GetField literalreturn null");
+ } else if (f.getType() == Boolean.TYPE
+ || f.getType() == Byte.TYPE
+ || f.getType() == Short.TYPE
+ || f.getType() == Integer.TYPE
+ || f.getType() == Long.TYPE) {
+ write(reference, "GetField literalreturn " + ret);
+ } else if (f.getType() == Float.TYPE
+ || f.getType() == Double.TYPE) {
+ write(reference, "GetField literalreturn " + String.format("%308.308e", ret));
+ } else if (f.getType() == Character.TYPE) {
+ write(reference, "GetField literalreturn " + (int) (Character) ret);
+ } else {
+ // Track returned object.
+ store.reference(ret);
+ write(reference, "GetField " + store.getIdentifier(ret));
+ }
+
+ } else if (message.startsWith("GetObjectClass")) {
+ int oid = Integer.parseInt(message.substring("GetObjectClass"
+ .length() + 1));
+ // System.out.println ("GETTING CLASS FOR: " + oid);
+ Class c = store.getObject(oid).getClass();
+ // System.out.println (" OBJ: " + store.getObject(oid));
+ // System.out.println (" CLS: " + c);
+ store.reference(c);
+
+ write(reference, "GetObjectClass " + store.getIdentifier(c));
+ } else if (message.startsWith("CallMethod") ||
+ message.startsWith("CallStaticMethod")) {
+ String[] args = message.split(" ");
+ Integer objectID = parseCall(args[1], null, Integer.class);
+ String methodName = parseCall(args[2], null, String.class);
+ Object o = null;
+ Class c;
+
+ if (message.startsWith("CallMethod")) {
+ o = (Object) store.getObject(objectID);
+ c = o.getClass();
+ } else {
+ c = (Class) store.getObject(objectID);
+ }
+
+ // length -3 to discard first 3, + 2 for holding object
+ // and method name
+ Object[] arguments = new Object[args.length - 1];
+ arguments[0] = c;
+ arguments[1] = methodName;
+ for (int i = 0; i < args.length - 3; i++) {
+ arguments[i+2] = store.getObject(parseCall(args[3 + i], null, Integer.class));
+ PluginDebug.debug("GOT ARG: " + arguments[i+2]);
+ }
+
+ Object[] matchingMethodAndArgs = MethodOverloadResolver.getMatchingMethod(arguments);
+
+ if (matchingMethodAndArgs == null) {
+ write(reference, "Error: No suitable method named " + methodName + " with matching args found");
+ return;
+ }
+
+ final Method m = (Method) matchingMethodAndArgs[0];
+ Object[] castedArgs = new Object[matchingMethodAndArgs.length - 1];
+ for (int i=0; i < castedArgs.length; i++) {
+ castedArgs[i] = matchingMethodAndArgs[i+1];
+ }
+
+ String collapsedArgs = "";
+ for (Object arg : castedArgs) {
+ collapsedArgs += " " + arg;
+ }
+
+ PluginDebug.debug("Calling method " + m + " on object " + o
+ + " (" + c + ") with " + collapsedArgs);
+
+ AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+ checkPermission(src, c, acc);
+
+ final Object[] fArguments = castedArgs;
+ final Object callableObject = o;
+ // Set the method accessible prior to calling. See:
+ // http://forums.sun.com/thread.jspa?threadID=332001&start=15&tstart=0
+ m.setAccessible(true);
+ Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
+ public Object run() {
+ try {
+ return m.invoke(callableObject, fArguments);
+ } catch (Throwable t) {
+ return t;
+ }
+ }
+ }, acc);
+
+ if (ret instanceof Throwable)
+ throw (Throwable) ret;
+
+ String retO;
+ if (ret == null) {
+ retO = "null";
+ } else {
+ retO = m.getReturnType().toString();
+ }
+
+ PluginDebug.debug("Calling " + m + " on " + o + " with "
+ + collapsedArgs + " and that returned: " + ret
+ + " of type " + retO);
+
+ if (m.getReturnType().equals(java.lang.Void.class) ||
+ m.getReturnType().equals(java.lang.Void.TYPE)) {
+ write(reference, "CallMethod literalreturn void");
+ } else if (ret == null) {
+ write(reference, "CallMethod literalreturn null");
+ } else if (m.getReturnType() == Boolean.TYPE
+ || m.getReturnType() == Byte.TYPE
+ || m.getReturnType() == Short.TYPE
+ || m.getReturnType() == Integer.TYPE
+ || m.getReturnType() == Long.TYPE) {
+ write(reference, "CallMethod literalreturn " + ret);
+ } else if (m.getReturnType() == Float.TYPE
+ || m.getReturnType() == Double.TYPE) {
+ write(reference, "CallMethod literalreturn " + String.format("%308.308e", ret));
+ } else if (m.getReturnType() == Character.TYPE) {
+ write(reference, "CallMethod literalreturn " + (int) (Character) ret);
+ } else {
+ // Track returned object.
+ store.reference(ret);
+ write(reference, "CallMethod " + store.getIdentifier(ret));
+ }
+ } else if (message.startsWith("GetSuperclass")) {
+ String[] args = message.split(" ");
+ Integer classID = parseCall(args[1], null, Integer.class);
+ Class c = null;
+ Class ret = null;
+
+ c = (Class) store.getObject(classID);
+ ret = c.getSuperclass();
+ store.reference(ret);
+
+ write(reference, "GetSuperclass " + store.getIdentifier(ret));
+ } else if (message.startsWith("IsAssignableFrom")) {
+ String[] args = message.split(" ");
+ Integer classID = parseCall(args[1], null, Integer.class);
+ Integer superclassID = parseCall(args[2], null, Integer.class);
+
+ boolean result = false;
+ Class clz = (Class) store.getObject(classID);
+ Class sup = (Class) store.getObject(superclassID);
+
+ result = sup.isAssignableFrom(clz);
+
+ write(reference, "IsAssignableFrom " + (result ? "1" : "0"));
+ } else if (message.startsWith("IsInstanceOf")) {
+ String[] args = message.split(" ");
+ Integer objectID = parseCall(args[1], null, Integer.class);
+ Integer classID = parseCall(args[2], null, Integer.class);
+
+ boolean result = false;
+ Object o = (Object) store.getObject(objectID);
+ Class c = (Class) store.getObject(classID);
+
+ result = c.isInstance(o);
+
+ write(reference, "IsInstanceOf " + (result ? "1" : "0"));
+ } else if (message.startsWith("GetStringUTFLength")) {
+ String[] args = message.split(" ");
+ Integer stringID = parseCall(args[1], null, Integer.class);
+
+ String o = null;
+ byte[] b = null;
+ o = (String) store.getObject(stringID);
+ b = o.getBytes("UTF-8");
+ // System.out.println ("STRING UTF-8 LENGTH: " + o + " " +
+ // b.length);
+
+ write(reference, "GetStringUTFLength " + o.length());
+ } else if (message.startsWith("GetStringLength")) {
+ String[] args = message.split(" ");
+ Integer stringID = parseCall(args[1], null, Integer.class);
+
+ String o = null;
+ byte[] b = null;
+ o = (String) store.getObject(stringID);
+ b = o.getBytes("UTF-16LE");
+ // System.out.println ("STRING UTF-16 LENGTH: " + o + " " +
+ // b.length);
+
+ // System.out.println ("Java: GetStringLength " + b.length);
+ write(reference, "GetStringLength " + o.length());
+ } else if (message.startsWith("GetStringUTFChars")) {
+ String[] args = message.split(" ");
+ Integer stringID = parseCall(args[1], null, Integer.class);
+
+ String o = null;
+ byte[] b = null;
+ StringBuffer buf = null;
+ o = (String) store.getObject(stringID);
+ b = o.getBytes("UTF-8");
+ buf = new StringBuffer(b.length * 2);
+ buf.append(b.length);
+ for (int i = 0; i < b.length; i++)
+ buf
+ .append(" "
+ + Integer
+ .toString(((int) b[i]) & 0x0ff, 16));
+
+ // System.out.println ("Java: GetStringUTFChars: " + o);
+ // //System.out.println ("String UTF BYTES: " + buf);
+ write(reference, "GetStringUTFChars " + buf);
+ } else if (message.startsWith("GetStringChars")) {
+ String[] args = message.split(" ");
+ Integer stringID = parseCall(args[1], null, Integer.class);
+
+ String o = null;
+ byte[] b = null;
+ StringBuffer buf = null;
+ o = (String) store.getObject(stringID);
+ // FIXME: LiveConnect uses UCS-2.
+ b = o.getBytes("UTF-16LE");
+ buf = new StringBuffer(b.length * 2);
+ buf.append(b.length);
+ for (int i = 0; i < b.length; i++)
+ buf
+ .append(" "
+ + Integer
+ .toString(((int) b[i]) & 0x0ff, 16));
+
+ PluginDebug.debug("Java: GetStringChars: " + o);
+ PluginDebug.debug(" String BYTES: " + buf);
+ write(reference, "GetStringChars " + buf);
+ } else if (message.startsWith("GetToStringValue")) {
+ String[] args = message.split(" ");
+ Integer objectID = parseCall(args[1], null, Integer.class);
+
+ String o = null;
+ byte[] b = null;
+ StringBuffer buf = null;
+ o = store.getObject(objectID).toString();
+ b = o.getBytes("UTF-8");
+ buf = new StringBuffer(b.length * 2);
+ buf.append(b.length);
+ for (int i = 0; i < b.length; i++)
+ buf
+ .append(" "
+ + Integer
+ .toString(((int) b[i]) & 0x0ff, 16));
+
+ write(reference, "GetToStringValue " + buf);
+ } else if (message.startsWith("NewArray")) {
+ String[] args = message.split(" ");
+ String type = parseCall(args[1], null, String.class);
+ Integer length = parseCall(args[2], null, Integer.class);
+
+ // System.out.println ("CALLING: NewArray: " + type + " " +
+ // length + " "
+ // + Signature.primitiveNameToType(type));
+
+ Object newArray = null;
+
+ Class c;
+ if (type.equals("bool")) {
+ c = Boolean.class;
+ } else if (type.equals("double")) {
+ c = Double.class;
+ } else if (type.equals("int")) {
+ c = Integer.class;
+ } else if (type.equals("string")) {
+ c = String.class;
+ } else if (isInt(type)) {
+ c = (Class) store.getObject(Integer.parseInt(type));
+ } else {
+ c = JSObject.class;
+ }
+
+ if (args.length > 3)
+ newArray = Array.newInstance(c, new int[] { length, parseCall(args[3], null, Integer.class)});
+ else
+ newArray = Array.newInstance(c, length);
+
+ store.reference(newArray);
+ write(reference, "NewArray " + store.getIdentifier(newArray));
+ } else if (message.startsWith("HasMethod")) {
+ String[] args = message.split(" ");
+ Integer classNameID = parseCall(args[1], null, Integer.class);
+ Integer methodNameID = parseCall(args[2], null, Integer.class);
+
+ Class c = (Class) store.getObject(classNameID);
+ String methodName = (String) store.getObject(methodNameID);
+
+ Method method = null;
+ Method[] classMethods = c.getMethods();
+ for (Method m: classMethods) {
+ if (m.getName().equals(methodName)) {
+ method = m;
+ break;
+ }
+ }
+
+ int hasMethod = (method != null) ? 1 : 0;
+
+ write(reference, "HasMethod " + hasMethod);
+ } else if (message.startsWith("HasPackage")) {
+ String[] args = message.split(" ");
+ Integer instance = parseCall(args[1], null, Integer.class);
+ Integer nameID = parseCall(args[2], null, Integer.class);
+ String pkgName = (String) store.getObject(nameID);
+
+ Package pkg = Package.getPackage(pkgName);
+ int hasPkg = (pkg != null) ? 1 : 0;
+
+ write(reference, "HasPackage " + hasPkg);
+
+ } else if (message.startsWith("HasField")) {
+ String[] args = message.split(" ");
+ Integer classNameID = parseCall(args[1], null, Integer.class);
+ Integer fieldNameID = parseCall(args[2], null, Integer.class);
+
+ Class c = (Class) store.getObject(classNameID);
+ String fieldName = (String) store.getObject(fieldNameID);
+
+ Field field = null;
+ Field[] classFields = c.getFields();
+ for (Field f: classFields) {
+ if (f.getName().equals(fieldName)) {
+ field = f;
+ break;
+ }
+ }
+
+ int hasField = (field != null) ? 1 : 0;
+
+ write(reference, "HasField " + hasField);
+ } else if (message.startsWith("NewObjectArray")) {
+ String[] args = message.split(" ");
+ Integer length = parseCall(args[1], null, Integer.class);
+ Integer classID = parseCall(args[2], null, Integer.class);
+ Integer objectID = parseCall(args[3], null, Integer.class);
+
+ // System.out.println ("CALLING: NewObjectArray: " +
+ // classID + " " + length + " "
+ // + objectID);
+
+ Object newArray = null;
+ newArray = Array.newInstance((Class) store.getObject(classID),
+ length);
+
+ Object[] array = (Object[]) newArray;
+ for (int i = 0; i < array.length; i++)
+ array[i] = store.getObject(objectID);
+ store.reference(newArray);
+ write(reference, "NewObjectArray "
+ + store.getIdentifier(newArray));
+ } else if (message.startsWith("NewObjectWithConstructor")) {
+
+ String[] args = message.split(" ");
+ Integer classID = parseCall(args[1], null, Integer.class);
+ Integer methodID = parseCall(args[2], null, Integer.class);
+
+ final Constructor m = (Constructor) store.getObject(methodID);
+ Class[] argTypes = m.getParameterTypes();
+
+ // System.out.println ("NEWOBJ: HERE1");
+ Object[] arguments = new Object[argTypes.length];
+ // System.out.println ("NEWOBJ: HERE2");
+ for (int i = 0; i < argTypes.length; i++) {
+ arguments[i] = parseArgs(args[3 + i], argTypes[i]);
+ // System.out.println ("NEWOBJ: GOT ARG: " + arguments[i]);
+ }
+
+ final Object[] fArguments = arguments;
+ AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+
+ Class c = (Class) store.getObject(classID);
+ checkPermission(src, c, acc);
+
+ Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
+ public Object run() {
+ try {
+ return m.newInstance(fArguments);
+ } catch (Throwable t) {
+ return t;
+ }
+ }
+ }, acc);
+
+ if (ret instanceof Throwable)
+ throw (Throwable) ret;
+
+ store.reference(ret);
+
+ write(reference, "NewObject " + store.getIdentifier(ret));
+
+ } else if (message.startsWith("NewObject")) {
+ String[] args = message.split(" ");
+ Integer classID = parseCall(args[1], null, Integer.class);
+ Class c = (Class) store.getObject(classID);
+ final Constructor cons;
+ final Object[] fArguments;
+
+ Object[] arguments = new Object[args.length - 1];
+ arguments[0] = c;
+ for (int i = 0; i < args.length - 2; i++) {
+ arguments[i + 1] = store.getObject(parseCall(args[2 + i],
+ null, Integer.class));
+ PluginDebug.debug("GOT ARG: " + arguments[i + 1]);
+ }
+
+ Object[] matchingConstructorAndArgs = MethodOverloadResolver
+ .getMatchingConstructor(arguments);
+
+ if (matchingConstructorAndArgs == null) {
+ write(reference,
+ "Error: No suitable constructor with matching args found");
+ return;
+ }
+
+ Object[] castedArgs = new Object[matchingConstructorAndArgs.length - 1];
+ for (int i = 0; i < castedArgs.length; i++) {
+ castedArgs[i] = matchingConstructorAndArgs[i + 1];
+ }
+
+ cons = (Constructor) matchingConstructorAndArgs[0];
+ fArguments = castedArgs;
+
+ String collapsedArgs = "";
+ for (Object arg : fArguments) {
+ collapsedArgs += " " + arg.toString();
+ }
+
+ PluginDebug.debug("Calling constructor on class " + c +
+ " with " + collapsedArgs);
+
+ AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+ checkPermission(src, c, acc);
+
+ Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
+ public Object run() {
+ try {
+ return cons.newInstance(fArguments);
+ } catch (Throwable t) {
+ return t;
+ }
+ }
+ }, acc);
+
+ if (ret instanceof Throwable)
+ throw (Throwable) ret;
+
+ store.reference(ret);
+
+ write(reference, "NewObject " + store.getIdentifier(ret));
+
+ } else if (message.startsWith("NewStringUTF")) {
+ PluginDebug.debug("MESSAGE: " + message);
+ String[] args = message.split(" ");
+ int length = new Integer(args[1]);
+ byte[] byteArray = new byte[length];
+ String ret = null;
+ int i = 0;
+ int j = 2;
+ int c;
+ while (i < length) {
+ c = Integer.parseInt(args[j++], 16);
+ byteArray[i++] = (byte) c;
+ }
+
+ ret = new String(byteArray, "UTF-8");
+ PluginDebug.debug("NEWSTRINGUTF: " + ret);
+
+ store.reference(ret);
+ write(reference, "NewStringUTF " + store.getIdentifier(ret));
+ } else if (message.startsWith("NewString")) {
+ PluginDebug.debug("MESSAGE: " + message);
+ String[] args = message.split(" ");
+ Integer strlength = parseCall(args[1], null, Integer.class);
+ int bytelength = 2 * strlength;
+ byte[] byteArray = new byte[bytelength];
+ String ret = null;
+ for (int i = 0; i < strlength; i++) {
+ int c = parseCall(args[2 + i], null, Integer.class);
+ PluginDebug.debug("char " + i + " " + c);
+ // Low.
+ byteArray[2 * i] = (byte) (c & 0x0ff);
+ // High.
+ byteArray[2 * i + 1] = (byte) ((c >> 8) & 0x0ff);
+ }
+ ret = new String(byteArray, 0, bytelength, "UTF-16LE");
+ PluginDebug.debug("NEWSTRING: " + ret);
+
+ // System.out.println ("NEWOBJ: CALLED: " + ret);
+ // System.out.println ("NEWOBJ: CALLED: " +
+ // store.getObject(ret));
+ store.reference(ret);
+ write(reference, "NewString " + store.getIdentifier(ret));
+
+ } else if (message.startsWith("ExceptionOccurred")) {
+ PluginDebug.debug("EXCEPTION: " + throwable);
+ if (throwable != null)
+ store.reference(throwable);
+ write(reference, "ExceptionOccurred "
+ + store.getIdentifier(throwable));
+ } else if (message.startsWith("ExceptionClear")) {
+ if (throwable != null && store.contains(throwable))
+ store.unreference(store.getIdentifier(throwable));
+ throwable = null;
+ write(reference, "ExceptionClear");
+ } else if (message.startsWith("DeleteGlobalRef")) {
+ String[] args = message.split(" ");
+ Integer id = parseCall(args[1], null, Integer.class);
+ store.unreference(id);
+ write(reference, "DeleteGlobalRef");
+ } else if (message.startsWith("DeleteLocalRef")) {
+ String[] args = message.split(" ");
+ Integer id = parseCall(args[1], null, Integer.class);
+ store.unreference(id);
+ write(reference, "DeleteLocalRef");
+ } else if (message.startsWith("NewGlobalRef")) {
+ String[] args = message.split(" ");
+ Integer id = parseCall(args[1], null, Integer.class);
+ store.reference(store.getObject(id));
+ write(reference, "NewGlobalRef " + id);
+ } else if (message.startsWith("GetClassName")) {
+ String[] args = message.split(" ");
+ Integer objectID = parseCall(args[1], null, Integer.class);
+ Object o = (Object) store.getObject(objectID);
+ write(reference, "GetClassName " + o.getClass().getName());
+ } else if (message.startsWith("GetClassID")) {
+ String[] args = message.split(" ");
+ Integer objectID = parseCall(args[1], null, Integer.class);
+ store.reference(store.getObject(objectID).getClass());
+ write(reference, "GetClassID " + store.getIdentifier(store.getObject(objectID).getClass()));
+ }
+ } catch (Throwable t) {
+ t.printStackTrace();
+ String msg = t.getCause() != null ? t.getCause().getMessage() : t.getMessage();
+
+ // add an identifier string to let javaside know of the type of error
+ // check for cause as well, since the top level exception will be InvocationTargetException in most cases
+ if (t instanceof AccessControlException || t.getCause() instanceof AccessControlException) {
+ msg = "LiveConnectPermissionNeeded " + msg;
+ }
+
+ write(reference, " Error " + msg);
+
+ // ExceptionOccured is only called after Callmethod() by mozilla. So
+ // for exceptions that are not related to CallMethod, we need a way
+ // to log them. This is how we do it.. send an error message to the
+ // c++ side to let it know that something went wrong, and it will do
+ // the right thing to let mozilla know
+
+ // Store the cause as the actual exception. This is needed because
+ // the exception we get here will always be an
+ // "InvocationTargetException" due to the use of reflection above
+ if (message.startsWith("CallMethod") || message.startsWith("CallStaticMethod"))
+ throwable = t.getCause();
+ }
+
+ }
+
+ /**
+ * Checks if the calling script is allowed to access the specified class
+ *
+ * @param jsSrc The source of the script
+ * @param target The target class that the script is trying to access
+ * @param acc AccessControlContext for this execution
+ * @throws AccessControlException If the script has insufficient permissions
+ */
+ public void checkPermission(String jsSrc, Class target, AccessControlContext acc) throws AccessControlException {
+ // NPRuntime does not allow cross-site calling. We therefore always
+ // allow this, for the time being
+ return;
+ }
+
+ private void write(int reference, String message) {
+ PluginDebug.debug("appletviewer writing " + message);
+ streamhandler.write("context " + identifier + " reference " + reference
+ + " " + message);
+ }
+
+ public void prePopulateLCClasses() {
+
+ int classID;
+
+ prepopulateClass("netscape/javascript/JSObject");
+ classID = prepopulateClass("netscape/javascript/JSException");
+ prepopulateMethod(classID, "<init>", "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;I)");
+ prepopulateMethod(classID, "<init>", "(ILjava/lang/Object;)");
+ prepopulateField(classID, "lineno");
+ prepopulateField(classID, "tokenIndex");
+ prepopulateField(classID, "source");
+ prepopulateField(classID, "filename");
+ prepopulateField(classID, "wrappedExceptionType");
+ prepopulateField(classID, "wrappedException");
+
+ classID = prepopulateClass("netscape/javascript/JSUtil");
+ prepopulateMethod(classID, "getStackTrace", "(Ljava/lang/Throwable;)");
+
+ prepopulateClass("java/lang/Object");
+ classID = prepopulateClass("java/lang/Class");
+ prepopulateMethod(classID, "getMethods", "()");
+ prepopulateMethod(classID, "getConstructors", "()");
+ prepopulateMethod(classID, "getFields", "()");
+ prepopulateMethod(classID, "getName", "()");
+ prepopulateMethod(classID, "isArray", "()");
+ prepopulateMethod(classID, "getComponentType", "()");
+ prepopulateMethod(classID, "getModifiers", "()");
+
+
+ classID = prepopulateClass("java/lang/reflect/Method");
+ prepopulateMethod(classID, "getName", "()");
+ prepopulateMethod(classID, "getParameterTypes", "()");
+ prepopulateMethod(classID, "getReturnType", "()");
+ prepopulateMethod(classID, "getModifiers", "()");
+
+ classID = prepopulateClass("java/lang/reflect/Constructor");
+ prepopulateMethod(classID, "getParameterTypes", "()");
+ prepopulateMethod(classID, "getModifiers", "()");
+
+ classID = prepopulateClass("java/lang/reflect/Field");
+ prepopulateMethod(classID, "getName", "()");
+ prepopulateMethod(classID, "getType", "()");
+ prepopulateMethod(classID, "getModifiers", "()");
+
+ classID = prepopulateClass("java/lang/reflect/Array");
+ prepopulateMethod(classID, "newInstance", "(Ljava/lang/Class;I)");
+
+ classID = prepopulateClass("java/lang/Throwable");
+ prepopulateMethod(classID, "toString", "()");
+ prepopulateMethod(classID, "getMessage", "()");
+
+ classID = prepopulateClass("java/lang/System");
+ prepopulateMethod(classID, "identityHashCode", "(Ljava/lang/Object;)");
+
+ classID = prepopulateClass("java/lang/Boolean");
+ prepopulateMethod(classID, "booleanValue", "()");
+ prepopulateMethod(classID, "<init>", "(Z)");
+
+ classID = prepopulateClass("java/lang/Double");
+ prepopulateMethod(classID, "doubleValue", "()");
+ prepopulateMethod(classID, "<init>", "(D)");
+
+ classID = prepopulateClass("java/lang/Void");
+ prepopulateField(classID, "TYPE");
+
+ prepopulateClass("java/lang/String");
+ prepopulateClass("java/applet/Applet");
+ }
+
+ private int prepopulateClass(String name) {
+ name = name.replace('/', '.');
+ ClassLoader cl = liveconnectLoader;
+ Class c = null;
+
+ try {
+ c = cl.loadClass(name);
+ store.reference(c);
+ } catch (ClassNotFoundException cnfe) {
+ // do nothing ... this should never happen
+ cnfe.printStackTrace();
+ }
+
+ return store.getIdentifier(c);
+ }
+
+ private int prepopulateMethod(int classID, String methodName, String signatureStr) {
+ Signature signature = parseCall(signatureStr, ((Class) store.getObject(classID)).getClassLoader(), Signature.class);
+ Object[] a = signature.getClassArray();
+
+ Class c = (Class) store.getObject(classID);
+ Method m = null;
+ Constructor cs = null;
+ Object o = null;
+
+ try {
+ if (methodName.equals("<init>")
+ || methodName.equals("<clinit>")) {
+ o = cs = c.getConstructor(signature.getClassArray());
+ store.reference(cs);
+ } else {
+ o = m = c.getMethod(methodName, signature.getClassArray());
+ store.reference(m);
+ }
+ } catch (NoSuchMethodException e) {
+ // should never happen
+ e.printStackTrace();
+ }
+
+ return store.getIdentifier(m);
+ }
+
+ private int prepopulateField(int classID, String fieldName) {
+
+ Class c = (Class) store.getObject(classID);
+ Field f = null;
+ try {
+ f = c.getField(fieldName);
+ } catch (SecurityException e) {
+ // should never happen
+ e.printStackTrace();
+ } catch (NoSuchFieldException e) {
+ // should never happen
+ e.printStackTrace();
+ }
+
+ store.reference(f);
+ return store.getIdentifier(f);
+ }
+
+ public void dumpStore() {
+ store.dump();
+ }
+
+ public Object getObject(int identifier) {
+ return store.getObject(identifier);
+ }
+
+ public int getIdentifier(Object o) {
+ return store.getIdentifier(o);
+ }
+
+ public void store(Object o) {
+ store.reference(o);
+ }
+
+ /**
+ * Returns a "closed" AccessControlContext i.e. no permissions to get out of sandbox.
+ */
+ public AccessControlContext getClosedAccessControlContext() {
+ // Deny everything
+ Permissions p = new Permissions();
+ ProtectionDomain pd = new ProtectionDomain(null, p);
+ return new AccessControlContext(new ProtectionDomain[] {pd});
+ }
+
+ public AccessControlContext getAccessControlContext(String[] nsPrivilegeList, String src) {
+
+/*
+ for (int i=0; i < nsPrivilegeList.length; i++) {
+ String privilege = nsPrivilegeList[i];
+
+ if (privilege.equals("UniversalAccept")) {
+ SocketPermission sp = new SocketPermission("*", "accept,resolve");
+ grantedPermissions.add(sp);
+ } else if (privilege.equals("UniversalAwtEventQueueAccess")) {
+ AWTPermission awtp = new AWTPermission("accessEventQueue");
+ grantedPermissions.add(awtp);
+ } else if (privilege.equals("UniversalConnect")) {
+ SocketPermission sp = new SocketPermission("*", "connect,resolve");
+ grantedPermissions.add(sp);
+ } else if (privilege.equals("UniversalListen")) {
+ SocketPermission sp = new SocketPermission("*", "listen,resolve");
+ grantedPermissions.add(sp);
+ } else if (privilege.equals("UniversalExecAccess")) {
+ FilePermission fp = new FilePermission("<<ALL FILES>>", "execute");
+ RuntimePermission rtp = new RuntimePermission("setIO");
+ grantedPermissions.add(fp);
+ grantedPermissions.add(rtp);
+ } else if (privilege.equals("UniversalExitAccess")) {
+ // Doesn't matter what the permissions are. Do not allow VM to exit.. we
+ // use a single VM for the entire browser lifecycle once invoked, we
+ // cannot let it exit
+
+ //RuntimePermission rtp = new RuntimePermission("exitVM.*");
+ //grantedPermissions.add(rtp);
+ } else if (privilege.equals("UniversalFileDelete")) {
+ FilePermission fp = new FilePermission("<<ALL FILES>>", "delete");
+ grantedPermissions.add(fp);
+ } else if (privilege.equals("UniversalFileRead")) {
+ FilePermission fp = new FilePermission("<<ALL FILES>>", "read");
+ grantedPermissions.add(fp);
+ } else if (privilege.equals("UniversalFileWrite")) {
+ FilePermission fp = new FilePermission("<<ALL FILES>>", "write");
+ grantedPermissions.add(fp);
+ } else if (privilege.equals("UniversalFdRead")) {
+ RuntimePermission rtp = new RuntimePermission("readFileDescriptor");
+ grantedPermissions.add(rtp);
+ } else if (privilege.equals("UniversalFdWrite")) {
+ RuntimePermission rtp = new RuntimePermission("writeFileDescriptor");
+ grantedPermissions.add(rtp);
+ } else if (privilege.equals("UniversalLinkAccess")) {
+ RuntimePermission rtp = new RuntimePermission("loadLibrary.*");
+ grantedPermissions.add(rtp);
+ } else if (privilege.equals("UniversalListen")) {
+ SocketPermission sp = new SocketPermission("*", "listen");
+ grantedPermissions.add(sp);
+ } else if (privilege.equals("UniversalMulticast")) {
+ SocketPermission sp = new SocketPermission("*", "accept,connect,resolve");
+ grantedPermissions.add(sp);
+ } else if (privilege.equals("UniversalPackageAccess")) {
+ RuntimePermission rtp = new RuntimePermission("defineClassInPackage.*");
+ grantedPermissions.add(rtp);
+ } else if (privilege.equals("UniversalPackageDefinition")) {
+ RuntimePermission rtp = new RuntimePermission("accessClassInPackage.*");
+ grantedPermissions.add(rtp);
+ } else if (privilege.equals("UniversalPrintJobAccess")) {
+ RuntimePermission rtp = new RuntimePermission("queuePrintJob");
+ grantedPermissions.add(rtp);
+ } else if (privilege.equals("UniversalPropertyRead")) {
+ PropertyPermission pp = new PropertyPermission("*", "read");
+ grantedPermissions.add(pp);
+ } else if (privilege.equals("UniversalPropertyWrite")) {
+ PropertyPermission pp = new PropertyPermission("*", "write");
+ grantedPermissions.add(pp);
+ } else if (privilege.equals("UniversalSetFactory")) {
+ RuntimePermission rtp = new RuntimePermission("setFactory");
+ grantedPermissions.add(rtp);
+ } else if (privilege.equals("UniversalSystemClipboardAccess")) {
+ AWTPermission awtp = new AWTPermission("accessClipboard");
+ grantedPermissions.add(awtp);
+ } else if (privilege.equals("UniversalThreadAccess")) {
+ RuntimePermission rtp1 = new RuntimePermission("modifyThread");
+ RuntimePermission rtp2 = new RuntimePermission("stopThread");
+ grantedPermissions.add(rtp1);
+ grantedPermissions.add(rtp2);
+ } else if (privilege.equals("UniversalThreadGroupAccess")) {
+ RuntimePermission rtp1 = new RuntimePermission("modifyThreadGroup");
+ RuntimePermission rtp2 = new RuntimePermission("modifyThread");
+ RuntimePermission rtp3 = new RuntimePermission("stopThread");
+ grantedPermissions.add(rtp1);
+ grantedPermissions.add(rtp2);
+ grantedPermissions.add(rtp3);
+ } else if (privilege.equals("UniversalTopLevelWindow")) {
+ AWTPermission awtp = new AWTPermission("topLevelWindow");
+ grantedPermissions.add(awtp);
+ } else if (privilege.equals("UniversalBrowserRead")) {
+ BrowserReadPermission bp = new BrowserReadPermission();
+ grantedPermissions.add(bp);
+ } else if (privilege.equals("UniversalJavaPermissions")) {
+ AllPermission ap = new AllPermission();
+ grantedPermissions.add(ap);
+ }
+ }
+
+ // what to do with these is unknown: UniversalConnectWithRedirect, UniversalDialogModality, UniversalSendMail, LimitedInstall, FullInstall, SilentInstall
+*/
+
+ Permissions grantedPermissions = new Permissions();
+
+ for (int i=0; i < nsPrivilegeList.length; i++) {
+ String privilege = nsPrivilegeList[i];
+
+ if (privilege.equals("UniversalBrowserRead")) {
+ BrowserReadPermission bp = new BrowserReadPermission();
+ grantedPermissions.add(bp);
+ } else if (privilege.equals("UniversalJavaPermission")) {
+ AllPermission ap = new AllPermission();
+ grantedPermissions.add(ap);
+ }
+ }
+
+ CodeSource cs = new CodeSource((URL) null, (java.security.cert.Certificate [])null);
+
+ if (src != null && src.length() > 0) {
+ try {
+ cs = new CodeSource(new URL(src + "/"), (java.security.cert.Certificate[]) null);
+ } catch (MalformedURLException mfue) {
+ // do nothing
+ }
+
+ if (src.equals("[System]"))
+ grantedPermissions.add(new JSObjectCreatePermission());
+
+ } else {
+ JSObjectCreatePermission perm = new JSObjectCreatePermission();
+ grantedPermissions.add(perm);
+ }
+
+ ProtectionDomain pd = new ProtectionDomain(cs, grantedPermissions, null, null);
+
+ // Add to hashmap
+ return new AccessControlContext(new ProtectionDomain[] {pd});
+ }
+
+ // private static final == inline
+ private static final boolean isInt(Object o) {
+ boolean isInt = false;
+
+ try {
+ Integer.parseInt((String) o);
+ isInt = true;
+ } catch (Exception e) {
+ // don't care
+ }
+
+ return isInt;
+ }
+
+ class BrowserReadPermission extends BasicPermission {
+ public BrowserReadPermission() {
+ super("browserRead");
+ }
+ }
+
+}