Mercurial > hg > release > icedtea6-1.4.1
changeset 1042:adaf3f0d6262
- Allow access to applet classloader from JS on that site (http://czateria.interia.pl/czat,room,70,Warszawa).
- Fix right-click lag by temporarily disabling status messages (any page with an applet...).
- Fix it so that applets with no height/width specifications can load.
- Fix hangs caused when Java->JS calls happened rapidly (http://www.rgagnon.com/examples/testcookie.html)
author | Deepak Bhole <dbhole@redhat.com> |
---|---|
date | Mon, 15 Sep 2008 17:11:17 -0400 |
parents | 02fc4b7ada3d |
children | 1c7da2861925 |
files | ChangeLog IcedTeaPlugin.cc patches/icedtea-liveconnect.patch |
diffstat | 3 files changed, 590 insertions(+), 355 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Mon Sep 15 11:20:54 2008 -0400 +++ b/ChangeLog Mon Sep 15 17:11:17 2008 -0400 @@ -1,3 +1,11 @@ +2008-08-26 Deepak Bhole <dbhole@redhat.com> + + * IcedTeaPlugin.cc: Allow access to applet classloader from JS on that + site. Fix right-click lag by temporarily disabling status messages. + * patches/icedtea-liveconnect.patch: Allow access to applet classloader + from JS on that site. Fix it so that applets with no height/width + specifications can load. + 2008-09-15 Lillian Angel <langel@redhat.com> * patches/icedtea-lc_ctype.patch: Fixed array size and
--- a/IcedTeaPlugin.cc Mon Sep 15 11:20:54 2008 -0400 +++ b/IcedTeaPlugin.cc Mon Sep 15 17:11:17 2008 -0400 @@ -308,20 +308,30 @@ "double", "void" }; +#include <nsIThread.h> + // FIXME: create index from security context. #define MESSAGE_CREATE(reference) \ + const char* addr; \ + GetCurrentPageAddress(&addr); \ +\ nsCString message ("context "); \ message.AppendInt (0); \ message += " reference "; \ message.AppendInt (reference); \ + if (factory->codebase_map.find(nsCString(addr)) != factory->codebase_map.end()) \ + { \ + message += " src "; \ + message += factory->codebase_map[nsCString(addr)];\ + } \ message += " "; \ message += __func__; \ - if (factory->resultMap[reference] == NULL) { \ - factory->resultMap[reference] = new ResultContainer(); \ - printf("ResultMap created -- %p %d\n", factory->resultMap[reference], factory->resultMap[reference]->returnIdentifier); \ + if (factory->result_map[reference] == NULL) { \ + factory->result_map[reference] = new ResultContainer(); \ + printf("ResultMap created -- %p %d\n", factory->result_map[reference], factory->result_map[reference]->returnIdentifier); \ } \ else \ - factory->resultMap[reference]->Clear(); + factory->result_map[reference]->Clear(); #define MESSAGE_ADD_STRING(name) \ @@ -387,7 +397,7 @@ #define PROCESS_PENDING_EVENTS_REF(reference) \ if (factory->shutting_down == PR_TRUE && \ - factory->resultMap[reference]->errorOccured == PR_TRUE) \ + factory->result_map[reference]->errorOccured == PR_TRUE) \ { \ printf("Error occured. Exiting function\n"); \ return NS_ERROR_FAILURE; \ @@ -414,46 +424,46 @@ #define MESSAGE_RECEIVE_REFERENCE(reference, cast, name) \ nsresult res = NS_OK; \ printf ("RECEIVE 1\n"); \ - while (factory->resultMap[reference]->returnIdentifier == -1) \ + while (factory->result_map[reference]->returnIdentifier == -1) \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ printf ("RECEIVE 3\n"); \ - if (factory->resultMap[reference]->returnIdentifier == 0) \ + if (factory->result_map[reference]->returnIdentifier == 0) \ { \ *name = NULL; \ } else { \ *name = \ reinterpret_cast<cast> \ - (factory->references.ReferenceObject (factory->resultMap[reference]->returnIdentifier)); \ + (factory->references.ReferenceObject (factory->result_map[reference]->returnIdentifier)); \ } \ printf ("RECEIVE_REFERENCE: %s result: %x = %d\n", \ - __func__, *name, factory->resultMap[reference]->returnIdentifier); + __func__, *name, factory->result_map[reference]->returnIdentifier); // FIXME: track and free JNIIDs. #define MESSAGE_RECEIVE_ID(reference, cast, id, signature) \ PRBool processed = PR_FALSE; \ nsresult res = NS_OK; \ printf("RECEIVE ID 1\n"); \ - while (factory->resultMap[reference]->returnIdentifier == -1) \ + while (factory->result_map[reference]->returnIdentifier == -1) \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ \ *id = reinterpret_cast<cast> \ - (new JNIID (factory->resultMap[reference]->returnIdentifier, signature)); \ + (new JNIID (factory->result_map[reference]->returnIdentifier, signature)); \ printf ("RECEIVE_ID: %s result: %x = %d, %s\n", \ - __func__, *id, factory->resultMap[reference]->returnIdentifier, \ + __func__, *id, factory->result_map[reference]->returnIdentifier, \ signature); #define MESSAGE_RECEIVE_VALUE(reference, ctype, result) \ nsresult res = NS_OK; \ printf("RECEIVE VALUE 1\n"); \ - while (factory->resultMap[reference]->returnValue == "") \ + while (factory->result_map[reference]->returnValue == "") \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ - *result = ParseValue (type, factory->resultMap[reference]->returnValue); + *result = ParseValue (type, factory->result_map[reference]->returnValue); // \ // char* valueString = ValueString (type, *result); \ // printf ("RECEIVE_VALUE: %s result: %x = %s\n", \ @@ -465,12 +475,12 @@ PRBool processed = PR_FALSE; \ nsresult res = NS_OK; \ printf("RECEIVE SIZE 1\n"); \ - while (factory->resultMap[reference]->returnValue == "") \ + while (factory->result_map[reference]->returnValue == "") \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ nsresult conversionResult; \ - *result = factory->resultMap[reference]->returnValue.ToInteger (&conversionResult); \ + *result = factory->result_map[reference]->returnValue.ToInteger (&conversionResult); \ PLUGIN_CHECK ("parse integer", conversionResult); // \ // printf ("RECEIVE_SIZE: %s result: %x = %d\n", \ @@ -481,13 +491,13 @@ PRBool processed = PR_FALSE; \ nsresult res = NS_OK; \ printf("RECEIVE STRING 1\n"); \ - while (factory->resultMap[reference]->returnValue == "") \ + while (factory->result_map[reference]->returnValue == "") \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ - printf("Setting result to: %s\n", strdup (factory->resultMap[reference]->returnValue.get ())); \ + printf("Setting result to: %s\n", strdup (factory->result_map[reference]->returnValue.get ())); \ *result = reinterpret_cast<char_type const*> \ - (strdup (factory->resultMap[reference]->returnValue.get ())); + (strdup (factory->result_map[reference]->returnValue.get ())); // \ // printf ("RECEIVE_STRING: %s result: %x = %s\n", \ // __func__, result, *result); @@ -497,15 +507,15 @@ PRBool processed = PR_FALSE; \ nsresult res = NS_OK; \ printf("RECEIVE STRING UCS 1\n"); \ - while (factory->resultMap[reference]->returnValueUCS.IsEmpty()) \ + while (factory->result_map[reference]->returnValueUCS.IsEmpty()) \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ - int length = factory->resultMap[reference]->returnValueUCS.Length (); \ + int length = factory->result_map[reference]->returnValueUCS.Length (); \ jchar* newstring = static_cast<jchar*> (PR_Malloc (length)); \ memset (newstring, 0, length); \ - memcpy (newstring, factory->resultMap[reference]->returnValueUCS.get (), length); \ - std::cout << "Setting result to: " << factory->resultMap[reference]->returnValueUCS.get() << std::endl; \ + memcpy (newstring, factory->result_map[reference]->returnValueUCS.get (), length); \ + std::cout << "Setting result to: " << factory->result_map[reference]->returnValueUCS.get() << std::endl; \ *result = static_cast<jchar const*> (newstring); // \ @@ -516,11 +526,11 @@ PRBool processed = PR_FALSE; \ nsresult res = NS_OK; \ printf("RECEIVE BOOLEAN 1\n"); \ - while (factory->resultMap[reference]->returnIdentifier == -1) \ + while (factory->result_map[reference]->returnIdentifier == -1) \ { \ PROCESS_PENDING_EVENTS_REF (reference); \ } \ - *result = factory->resultMap[reference]->returnIdentifier; + *result = factory->result_map[reference]->returnIdentifier; // res = factory->current->ProcessNextEvent (PR_TRUE, \ // &processed); \ // PLUGIN_CHECK_RETURN (__func__, res); \ @@ -767,7 +777,7 @@ // FIXME: make private? JNIEnv* proxyEnv; nsISecureEnv* secureEnv; - std::map<PRUint32,ResultContainer*> resultMap; + std::map<PRUint32,ResultContainer*> result_map; void GetMember (); void SetMember (); void GetSlot (); @@ -778,6 +788,7 @@ void Finalize (); void ToString (); nsCOMPtr<nsILiveconnect> liveconnect; + std::map<nsCString, nsCString> codebase_map; private: ~IcedTeaPluginFactory(); @@ -828,7 +839,6 @@ class IcedTeaEventSink; - class IcedTeaPluginInstance : public nsIPluginInstance, public nsIJVMPluginInstance { @@ -1139,6 +1149,7 @@ int IncrementContextCounter(); void DecrementContextCounter(); + void GetCurrentPageAddress(const char **addr); int contextCounter; }; @@ -2068,6 +2079,29 @@ NS_ADDREF (aPeer); printf ("DONE SETTING PEER!!!: %p\n", aPeer); +// if (factory->codebase_map[nsCString(documentbase)] != NULL) +// { +// printf("Found %s in map and it is %s\n", nsCString(documentbase), factory->codebase_map[nsCString(documentbase)].get()); +// +// } + + nsCString dbase(documentbase); + if (factory->codebase_map.find(dbase) != factory->codebase_map.end()) + { + factory->codebase_map[dbase] += ","; + factory->codebase_map[dbase].AppendInt(instance_identifier); + + printf("Appended: %s to %s\n", factory->codebase_map[dbase].get(), documentbase); + + } else + { + nsCString str; + str.AppendInt(instance_identifier); + factory->codebase_map[dbase] = str; + + printf("Creating and adding %s to %s and we now have: %s\n", str.get(), documentbase, factory->codebase_map.find(dbase)->second.get()); + } + return NS_OK; } @@ -2138,9 +2172,8 @@ printf("IcedTeaPluginInstance::SetWindow: Instance %p waiting for initialization...\n", this); - while (initialized == PR_FALSE) { + while (initialized == PR_FALSE) { PROCESS_PENDING_EVENTS; -// printf("waiting for java object\n"); } printf("Instance %p initialization complete...\n", this); @@ -2308,7 +2341,7 @@ objectMessage.AppendInt (reference); objectMessage += " GetJavaObject"; printf ("Sending object message: %s\n", objectMessage.get()); - resultMap[reference] = new ResultContainer(); + result_map[reference] = new ResultContainer(); SendMessageToAppletViewer (objectMessage); PRBool processed = PR_FALSE; @@ -2439,8 +2472,8 @@ { IcedTeaPluginInstance* instance = NULL; instances.Get (identifier, &instance); - if (instance != 0) - instance->peer->ShowStatus (nsCString (rest).get ()); +// if (instance != 0) +// instance->peer->ShowStatus (nsCString (rest).get ()); } else if (command == "initialized") { @@ -2658,7 +2691,7 @@ else if (command == "Error") { printf("Error occured. Setting error flag for container @ %d to true\n", reference); - resultMap[reference]->errorOccured = PR_TRUE; + result_map[reference]->errorOccured = PR_TRUE; } } else if (prefix == "context") @@ -2694,9 +2727,9 @@ || command == "NewGlobalRef" || command == "NewArray") { - resultMap[reference]->returnIdentifier = rest.ToInteger (&conversionResult); + result_map[reference]->returnIdentifier = rest.ToInteger (&conversionResult); PLUGIN_CHECK ("parse integer", conversionResult); - printf ("GOT RETURN IDENTIFIER %d\n", resultMap[reference]->returnIdentifier); + printf ("GOT RETURN IDENTIFIER %d\n", result_map[reference]->returnIdentifier); } else if (command == "GetField" @@ -2710,8 +2743,8 @@ // if (returnValue != "") // PLUGIN_ERROR ("Return value already defined."); - resultMap[reference]->returnValue = rest; - printf ("PLUGIN GOT RETURN VALUE: %s\n", resultMap[reference]->returnValue.get()); + result_map[reference]->returnValue = rest; + printf ("PLUGIN GOT RETURN VALUE: %s\n", result_map[reference]->returnValue.get()); } else if (command == "GetStringUTFChars") { @@ -2739,8 +2772,8 @@ offset - previousOffset).ToInteger (&conversionResult, 16)); PLUGIN_CHECK ("parse integer", conversionResult); } - resultMap[reference]->returnValue = returnValue; - printf ("PLUGIN GOT RETURN UTF-8 STRING: %s\n", resultMap[reference]->returnValue.get ()); + result_map[reference]->returnValue = returnValue; + printf ("PLUGIN GOT RETURN UTF-8 STRING: %s\n", result_map[reference]->returnValue.get ()); } else if (command == "GetStringChars") { @@ -2792,7 +2825,7 @@ printf ("?"); } printf ("\n"); - resultMap[reference]->returnValueUCS = returnValueUCS; + result_map[reference]->returnValueUCS = returnValueUCS; } // Do nothing for: SetStaticField, SetField, ExceptionClear, @@ -3726,6 +3759,10 @@ #include <nsNetCID.h> #include <nsServiceManagerUtils.h> #include <iostream> +#include <jvmmgr.h> +#include <nsIPrincipal.h> +#include <nsIScriptSecurityManager.h> +#include <nsIURI.h> IcedTeaJNIEnv::IcedTeaJNIEnv (IcedTeaPluginFactory* factory) : factory (factory) @@ -3764,6 +3801,29 @@ PR_ExitMonitor(contextCounterPRMonitor); } +void +IcedTeaJNIEnv::GetCurrentPageAddress(const char **addr) +{ + nsIPrincipal *prin; + nsCOMPtr<nsIScriptSecurityManager> sec_man(do_GetService("@mozilla.org/scriptsecuritymanager;1")); + + sec_man->GetSubjectPrincipal(&prin); + + if (prin) + { + + nsIURI *uri; + prin->GetURI(&uri); + + if (uri) + { + nsCAutoString str; + uri->GetSpec(str); + NS_CStringGetData(str, addr); + } + } +} + NS_IMETHODIMP IcedTeaJNIEnv::NewObject (jclass clazz, jmethodID methodID, @@ -3781,6 +3841,7 @@ printf("MSG SEND COMPLETE. NOW RECEIVING...\n"); MESSAGE_RECEIVE_REFERENCE (reference, jobject, result); DecrementContextCounter (); + return NS_OK; } @@ -3803,6 +3864,7 @@ printf("MSG SEND COMPLETE. NOW RECEIVING...\n"); MESSAGE_RECEIVE_VALUE (reference, type, result); DecrementContextCounter (); + return NS_OK; } @@ -3816,6 +3878,7 @@ jvalue* result, nsISecurityContext* ctx) { + NOT_IMPLEMENTED (); return NS_ERROR_NOT_IMPLEMENTED; } @@ -3975,7 +4038,7 @@ i = 1; stopchar = ')'; } - + // Method. int arg = 0; char* fl; @@ -3999,9 +4062,11 @@ retstr.AppendInt (args[arg].s); break; case 'I': + printf("Appending (I @ %d) %d\n", arg, args[arg].i); retstr.AppendInt (args[arg].i); break; case 'J': + printf("Appending (J @ %d) %d\n", arg, args[arg].i); retstr.AppendInt (args[arg].j); break; case 'F': @@ -4011,6 +4076,7 @@ retstr += IcedTeaPrintfCString ("%g", args[arg].d); break; case 'L': + std::cout << "Appending for L: arg=" << arg << " args[arg].l=" << args[arg].l << std::endl; retstr.AppendInt (ID (args[arg].l)); i++; while (id->signature[i] != ';') @@ -4044,7 +4110,10 @@ printf ("FAILED ID: %d\n", id->identifier); break; } + + retstr += " "; i++; + arg++; } // Freed by calling function. @@ -4067,6 +4136,7 @@ printf("MSG SEND COMPLETE. NOW RECEIVING...\n"); MESSAGE_RECEIVE_VALUE (reference, type, result); DecrementContextCounter (); + return NS_OK; } @@ -4084,7 +4154,7 @@ MESSAGE_ADD_ID (fieldID); MESSAGE_ADD_VALUE (fieldID, val); MESSAGE_SEND (); - printf("MSG SEND COMPLETE. NOW RECEIVING...\n"); + return NS_OK; } @@ -4106,6 +4176,7 @@ printf("MSG SEND COMPLETE. NOW RECEIVING...\n"); MESSAGE_RECEIVE_VALUE (reference, type, result); DecrementContextCounter (); + return NS_OK; } @@ -4125,6 +4196,7 @@ printf("MSG SEND COMPLETE. NOW RECEIVING...\n"); MESSAGE_RECEIVE_VALUE (reference, type, result); DecrementContextCounter (); + return NS_OK; } @@ -4142,7 +4214,7 @@ MESSAGE_ADD_ID (fieldID); MESSAGE_ADD_VALUE (fieldID, val); MESSAGE_SEND (); - printf("MSG SEND COMPLETE. NOW RECEIVING...\n"); + return NS_OK; } @@ -4799,12 +4871,15 @@ PLUGIN_DEBUG("Waiting for factory to be created..."); } + + PLUGIN_DEBUG("NSGetFactory: Returning existing factory"); + *aFactory = factory; NS_ADDREF (factory); } else { factory_created = PR_TRUE; - PLUGIN_DEBUG("Creating factory"); + PLUGIN_DEBUG("NSGetFactory: Creating factory"); factory = new IcedTeaPluginFactory (); if (!factory) return NS_ERROR_OUT_OF_MEMORY;
--- a/patches/icedtea-liveconnect.patch Mon Sep 15 11:20:54 2008 -0400 +++ b/patches/icedtea-liveconnect.patch Mon Sep 15 17:11:17 2008 -0400 @@ -1,6 +1,6 @@ diff -urN openjdk.orig/jdk/make/sun/Makefile openjdk/jdk/make/sun/Makefile --- openjdk.orig/jdk/make/sun/Makefile 2008-07-10 15:54:44.000000000 -0400 -+++ openjdk/jdk/make/sun/Makefile 2008-08-26 17:23:07.000000000 -0400 ++++ openjdk/jdk/make/sun/Makefile 2008-09-15 16:21:47.000000000 -0400 @@ -66,6 +66,7 @@ $(HEADLESS_SUBDIR) $(DGA_SUBDIR) \ font jpeg cmm applet rmi beans $(JDBC_SUBDIR) \ @@ -11,7 +11,7 @@ all build clean clobber:: diff -urN openjdk.orig/jdk/make/sun/Makefile.orig openjdk/jdk/make/sun/Makefile.orig --- openjdk.orig/jdk/make/sun/Makefile.orig 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/make/sun/Makefile.orig 2008-08-26 17:23:07.000000000 -0400 ++++ openjdk/jdk/make/sun/Makefile.orig 2008-09-15 16:21:47.000000000 -0400 @@ -0,0 +1,73 @@ +# +# Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved. @@ -88,7 +88,7 @@ + diff -urN openjdk.orig/jdk/make/sun/plugin/Makefile openjdk/jdk/make/sun/plugin/Makefile --- openjdk.orig/jdk/make/sun/plugin/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/make/sun/plugin/Makefile 2008-08-26 17:23:07.000000000 -0400 ++++ openjdk/jdk/make/sun/plugin/Makefile 2008-09-15 16:21:47.000000000 -0400 @@ -0,0 +1,53 @@ +# +# Copyright 1995-2005 Sun Microsystems, Inc. All Rights Reserved. @@ -145,8 +145,8 @@ + diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/GetMemberPluginCallRequest.java openjdk/jdk/src/share/classes/sun/applet/GetMemberPluginCallRequest.java --- openjdk.orig/jdk/src/share/classes/sun/applet/GetMemberPluginCallRequest.java 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/src/share/classes/sun/applet/GetMemberPluginCallRequest.java 2008-07-20 22:33:37.000000000 -0400 -@@ -0,0 +1,58 @@ ++++ openjdk/jdk/src/share/classes/sun/applet/GetMemberPluginCallRequest.java 2008-09-15 16:22:06.000000000 -0400 +@@ -0,0 +1,72 @@ +/* GetMemberPluginCallRequest -- represent Java-to-JavaScript requests + Copyright (C) 2008 Red Hat + @@ -203,12 +203,26 @@ + 0).store.getObject(Integer.parseInt(args[1])); + done = true; + } ++ ++ /** ++ * Returns whether the given message is serviceable by this object ++ * ++ * @param message The message to service ++ * @return boolean indicating if message is serviceable ++ */ ++ public boolean serviceable(String message) { ++ return message.contains("JavaScriptCall") || ++ message.contains("JavaScriptEval") || ++ message.contains("JavaScriptGetMember") || ++ message.contains("JavaScriptGetSlot") || ++ message.contains("JavaScriptToString"); ++ } +} + diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/GetWindowPluginCallRequest.java openjdk/jdk/src/share/classes/sun/applet/GetWindowPluginCallRequest.java --- openjdk.orig/jdk/src/share/classes/sun/applet/GetWindowPluginCallRequest.java 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/src/share/classes/sun/applet/GetWindowPluginCallRequest.java 2008-07-20 22:33:34.000000000 -0400 -@@ -0,0 +1,56 @@ ++++ openjdk/jdk/src/share/classes/sun/applet/GetWindowPluginCallRequest.java 2008-09-15 16:22:06.000000000 -0400 +@@ -0,0 +1,66 @@ +/* GetWindowPluginCallRequest -- represent Java-to-JavaScript requests + Copyright (C) 2008 Red Hat + @@ -264,11 +278,21 @@ + internal = Integer.parseInt(args[1]); + done = true; + } ++ ++ /** ++ * Returns whether the given message is serviceable by this object ++ * ++ * @param message The message to service ++ * @return boolean indicating if message is serviceable ++ */ ++ public boolean serviceable(String message) { ++ return message.contains("JavaScriptGetWindow"); ++ } +} diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/PluginAppletSecurityContext.java openjdk/jdk/src/share/classes/sun/applet/PluginAppletSecurityContext.java --- openjdk.orig/jdk/src/share/classes/sun/applet/PluginAppletSecurityContext.java 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/src/share/classes/sun/applet/PluginAppletSecurityContext.java 2008-09-04 17:01:37.000000000 -0400 -@@ -0,0 +1,807 @@ ++++ openjdk/jdk/src/share/classes/sun/applet/PluginAppletSecurityContext.java 2008-09-15 16:22:07.000000000 -0400 +@@ -0,0 +1,847 @@ +/* PluginAppletSecurityContext -- execute plugin JNI messages + Copyright (C) 2008 Red Hat + @@ -308,9 +332,14 @@ + +package sun.applet; + -+import java.util.*; -+import java.lang.reflect.*; -+import java.io.*; ++import java.lang.reflect.Array; ++import java.lang.reflect.Constructor; ++import java.lang.reflect.Field; ++import java.lang.reflect.Method; ++import java.util.ArrayList; ++import java.util.HashMap; ++import java.util.List; ++import java.util.StringTokenizer; + +class Signature { + private String signature; @@ -378,7 +407,7 @@ + } + } + -+ public Signature(String signature) { ++ public Signature(String signature, String src) { + this.signature = signature; + currentIndex = 0; + typeList = new ArrayList<Class>(10); @@ -388,40 +417,36 @@ + elem = nextTypeName(); + // System.out.println ("NEXT TYPE: " + elem); + Class primitive = primitiveNameToType(elem); -+ try { -+ 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); ++ 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.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( -+ Class.forName(arrayType), dims).getClass()); -+ } else { -+ typeList.add(Class.forName(elem)); ++ // 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, src), dims).getClass()); ++ } else { ++ typeList.add(getClass(elem, src)); + } -+ } catch (ClassNotFoundException e) { -+ throw new RuntimeException(e); + } + } + if (typeList.size() == 0) { @@ -430,6 +455,39 @@ + } + } + ++ public static Class getClass(String name, String src) { ++ ++ Class c = null; ++ ++ try { ++ c = Class.forName(name); ++ } catch (ClassNotFoundException cnfe) { ++ ++ StringTokenizer st = new StringTokenizer(src, ","); ++ ++ while (st.hasMoreTokens()) { ++ ++ String tok = st.nextToken(); ++ System.err.println("Searching for " + name + " at key " + tok); ++ ++ try { ++ c = PluginAppletSecurityContext.classLoaders.get(tok).loadClass(name); ++ } catch (ClassNotFoundException e) { ++ // do nothing .. thrown below ++ } ++ ++ if (c != null) ++ break; ++ } ++ } ++ ++ if (c == null) { ++ 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; @@ -462,6 +520,8 @@ + // Context identifier -> PluginAppletSecurityContext object. + // FIXME: make private + public static HashMap<Integer, PluginAppletSecurityContext> contexts = new HashMap(); ++ ++ public static HashMap<String, ClassLoader> classLoaders = new HashMap<String, ClassLoader>(); + + // FIXME: make private + public PluginObjectStore store = new PluginObjectStore(); @@ -470,7 +530,10 @@ + int identifier = 0; + + static { -+ // FIXME: when should we add each new security context? ++ // FIXME: when should we add each new security context? but how would ++ // we be able to know which context applies to which request from nspr? ++ // the nspr jni functions do not know what applet they are being called ++ // in reference to + contexts.put(0, new PluginAppletSecurityContext(0)); + } + @@ -478,13 +541,13 @@ + this.identifier = identifier; + } + -+ public static <V> V parseCall(String s, Class<V> c) { ++ public static <V> V parseCall(String s, String src, 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); ++ return (V) new Signature(s, src); + else + throw new RuntimeException("Unexpected call value."); + } @@ -514,12 +577,13 @@ + return store.getObject(new Integer(s)); + } + -+ public static void handleMessage(int identifier, int reference, ++ public static void handleMessage(int identifier, String src, int reference, + String message) { -+ contexts.get(identifier).handleMessage(reference, message); ++ contexts.get(identifier).handleMessage(reference, src, message); + } + -+ public void handleMessage(int reference, String message) { ++ public void handleMessage(int reference, String src, String message) { ++ + try { + if (message.startsWith("FindClass")) { + ClassLoader cl = null; @@ -539,9 +603,9 @@ + } else if (message.startsWith("GetStaticMethodID") + || message.startsWith("GetMethodID")) { + String[] args = message.split(" "); -+ Integer classID = parseCall(args[1], Integer.class); -+ String methodName = parseCall(args[2], String.class); -+ Signature signature = parseCall(args[3], Signature.class); ++ Integer classID = parseCall(args[1], src, Integer.class); ++ String methodName = parseCall(args[2], src, String.class); ++ Signature signature = parseCall(args[3], src, Signature.class); + Object[] a = signature.getClassArray(); + + Class c = (Class) store.getObject(classID); @@ -561,9 +625,9 @@ + } else if (message.startsWith("GetStaticFieldID") + || message.startsWith("GetFieldID")) { + String[] args = message.split(" "); -+ Integer classID = parseCall(args[1], Integer.class); -+ String fieldName = parseCall(args[2], String.class); -+ Signature signature = parseCall(args[3], Signature.class); ++ Integer classID = parseCall(args[1], src, Integer.class); ++ String fieldName = parseCall(args[2], src, String.class); ++ Signature signature = parseCall(args[3], src, Signature.class); + + Class c = (Class) store.getObject(classID); + Field f = null; @@ -574,9 +638,9 @@ + write(reference, "GetStaticFieldID " + store.getIdentifier(f)); + } else if (message.startsWith("GetStaticField")) { + String[] args = message.split(" "); -+ String type = parseCall(args[1], String.class); -+ Integer classID = parseCall(args[1], Integer.class); -+ Integer fieldID = parseCall(args[2], Integer.class); ++ String type = parseCall(args[1], src, String.class); ++ Integer classID = parseCall(args[1], src, Integer.class); ++ Integer fieldID = parseCall(args[2], src, Integer.class); + + Class c = (Class) store.getObject(classID); + Field f = (Field) store.getObject(fieldID); @@ -604,9 +668,9 @@ + } + } else if (message.startsWith("SetStaticField")) { + String[] args = message.split(" "); -+ String type = parseCall(args[1], String.class); -+ Integer classID = parseCall(args[2], Integer.class); -+ Integer fieldID = parseCall(args[3], Integer.class); ++ String type = parseCall(args[1], src, String.class); ++ Integer classID = parseCall(args[2], src, Integer.class); ++ Integer fieldID = parseCall(args[3], src, Integer.class); + + Object value = null; + if (Signature.primitiveNameToType(type) != null) { @@ -626,9 +690,9 @@ + write(reference, "SetStaticField"); + } else if (message.startsWith("SetField")) { + String[] args = message.split(" "); -+ String type = parseCall(args[1], String.class); -+ Integer objectID = parseCall(args[2], Integer.class); -+ Integer fieldID = parseCall(args[3], Integer.class); ++ String type = parseCall(args[1], src, String.class); ++ Integer objectID = parseCall(args[2], src, Integer.class); ++ Integer fieldID = parseCall(args[3], src, Integer.class); + + Object value = null; + if (Signature.primitiveNameToType(type) != null) { @@ -648,8 +712,8 @@ + write(reference, "SetField"); + } else if (message.startsWith("GetObjectArrayElement")) { + String[] args = message.split(" "); -+ Integer arrayID = parseCall(args[1], Integer.class); -+ Integer index = parseCall(args[2], Integer.class); ++ Integer arrayID = parseCall(args[1], src, Integer.class); ++ Integer index = parseCall(args[2], src, Integer.class); + + Object[] o = (Object[]) store.getObject(arrayID); + Object ret = null; @@ -663,9 +727,9 @@ + + store.getIdentifier(ret)); + } else if (message.startsWith("SetObjectArrayElement")) { + String[] args = message.split(" "); -+ Integer arrayID = parseCall(args[1], Integer.class); -+ Integer index = parseCall(args[2], Integer.class); -+ Integer objectID = parseCall(args[3], Integer.class); ++ Integer arrayID = parseCall(args[1], src, Integer.class); ++ Integer index = parseCall(args[2], src, Integer.class); ++ Integer objectID = parseCall(args[3], src, Integer.class); + + Object[] o = (Object[]) store.getObject(arrayID); + Object toSet = (Object) store.getObject(objectID); @@ -675,7 +739,7 @@ + write(reference, "SetObjectArrayElement"); + } else if (message.startsWith("GetArrayLength")) { + String[] args = message.split(" "); -+ Integer arrayID = parseCall(args[1], Integer.class); ++ Integer arrayID = parseCall(args[1], src, Integer.class); + + System.out.println("ARRAYID: " + arrayID); + Object o = (Object) store.getObject(arrayID); @@ -687,9 +751,9 @@ + write(reference, "GetArrayLength " + Array.getLength(o)); + } else if (message.startsWith("GetField")) { + String[] args = message.split(" "); -+ String type = parseCall(args[1], String.class); -+ Integer objectID = parseCall(args[1], Integer.class); -+ Integer fieldID = parseCall(args[2], Integer.class); ++ String type = parseCall(args[1], src, String.class); ++ Integer objectID = parseCall(args[1], src, Integer.class); ++ Integer fieldID = parseCall(args[2], src, Integer.class); + + Object o = (Object) store.getObject(objectID); + Field f = (Field) store.getObject(fieldID); @@ -726,8 +790,8 @@ + write(reference, "GetObjectClass " + store.getIdentifier(c)); + } else if (message.startsWith("CallStaticMethod")) { + String[] args = message.split(" "); -+ Integer classID = parseCall(args[1], Integer.class); -+ Integer methodID = parseCall(args[2], Integer.class); ++ Integer classID = parseCall(args[1], src, Integer.class); ++ Integer methodID = parseCall(args[2], src, Integer.class); + + System.out.println("GETTING: " + methodID); + Method m = (Method) store.getObject(methodID); @@ -773,8 +837,8 @@ + } + } else if (message.startsWith("CallMethod")) { + String[] args = message.split(" "); -+ Integer objectID = parseCall(args[1], Integer.class); -+ Integer methodID = parseCall(args[2], Integer.class); ++ Integer objectID = parseCall(args[1], src, Integer.class); ++ Integer methodID = parseCall(args[2], src, Integer.class); + + Object o = (Object) store.getObject(objectID); + Method m = (Method) store.getObject(methodID); @@ -830,7 +894,7 @@ + } + } else if (message.startsWith("GetSuperclass")) { + String[] args = message.split(" "); -+ Integer classID = parseCall(args[1], Integer.class); ++ Integer classID = parseCall(args[1], src, Integer.class); + Class c = null; + Class ret = null; + @@ -841,8 +905,8 @@ + write(reference, "GetSuperclass " + store.getIdentifier(ret)); + } else if (message.startsWith("IsAssignableFrom")) { + String[] args = message.split(" "); -+ Integer classID = parseCall(args[1], Integer.class); -+ Integer superclassID = parseCall(args[2], Integer.class); ++ Integer classID = parseCall(args[1], src, Integer.class); ++ Integer superclassID = parseCall(args[2], src, Integer.class); + + boolean result = false; + Class clz = (Class) store.getObject(classID); @@ -853,8 +917,8 @@ + write(reference, "IsAssignableFrom " + (result ? "1" : "0")); + } else if (message.startsWith("IsInstanceOf")) { + String[] args = message.split(" "); -+ Integer objectID = parseCall(args[1], Integer.class); -+ Integer classID = parseCall(args[2], Integer.class); ++ Integer objectID = parseCall(args[1], src, Integer.class); ++ Integer classID = parseCall(args[2], src, Integer.class); + + boolean result = false; + Object o = (Object) store.getObject(objectID); @@ -865,7 +929,7 @@ + write(reference, "IsInstanceOf " + (result ? "1" : "0")); + } else if (message.startsWith("GetStringUTFLength")) { + String[] args = message.split(" "); -+ Integer stringID = parseCall(args[1], Integer.class); ++ Integer stringID = parseCall(args[1], src, Integer.class); + + String o = null; + byte[] b = null; @@ -877,7 +941,7 @@ + write(reference, "GetStringUTFLength " + o.length()); + } else if (message.startsWith("GetStringLength")) { + String[] args = message.split(" "); -+ Integer stringID = parseCall(args[1], Integer.class); ++ Integer stringID = parseCall(args[1], src, Integer.class); + + String o = null; + byte[] b = null; @@ -890,7 +954,7 @@ + write(reference, "GetStringLength " + o.length()); + } else if (message.startsWith("GetStringUTFChars")) { + String[] args = message.split(" "); -+ Integer stringID = parseCall(args[1], Integer.class); ++ Integer stringID = parseCall(args[1], src, Integer.class); + + String o = null; + byte[] b = null; @@ -910,7 +974,7 @@ + write(reference, "GetStringUTFChars " + buf); + } else if (message.startsWith("GetStringChars")) { + String[] args = message.split(" "); -+ Integer stringID = parseCall(args[1], Integer.class); ++ Integer stringID = parseCall(args[1], src, Integer.class); + + String o = null; + byte[] b = null; @@ -931,8 +995,8 @@ + write(reference, "GetStringChars " + buf); + } else if (message.startsWith("NewArray")) { + String[] args = message.split(" "); -+ String type = parseCall(args[1], String.class); -+ Integer length = parseCall(args[2], Integer.class); ++ String type = parseCall(args[1], src, String.class); ++ Integer length = parseCall(args[2], src, Integer.class); + + // System.out.println ("CALLING: NewArray: " + type + " " + + // length + " " @@ -946,9 +1010,9 @@ + write(reference, "NewArray " + store.getIdentifier(newArray)); + } else if (message.startsWith("NewObjectArray")) { + String[] args = message.split(" "); -+ Integer length = parseCall(args[1], Integer.class); -+ Integer classID = parseCall(args[2], Integer.class); -+ Integer objectID = parseCall(args[3], Integer.class); ++ Integer length = parseCall(args[1], src, Integer.class); ++ Integer classID = parseCall(args[2], src, Integer.class); ++ Integer objectID = parseCall(args[3], src, Integer.class); + + // System.out.println ("CALLING: NewObjectArray: " + + // classID + " " + length + " " @@ -966,8 +1030,8 @@ + + store.getIdentifier(newArray)); + } else if (message.startsWith("NewObject")) { + String[] args = message.split(" "); -+ Integer classID = parseCall(args[1], Integer.class); -+ Integer methodID = parseCall(args[2], Integer.class); ++ Integer classID = parseCall(args[1], src, Integer.class); ++ Integer methodID = parseCall(args[2], src, Integer.class); + + Constructor m = (Constructor) store.getObject(methodID); + Class[] argTypes = m.getParameterTypes(); @@ -992,12 +1056,12 @@ + } else if (message.startsWith("NewString")) { + System.out.println("MESSAGE: " + message); + String[] args = message.split(" "); -+ Integer strlength = parseCall(args[1], Integer.class); ++ Integer strlength = parseCall(args[1], src, 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], Integer.class); ++ int c = parseCall(args[2 + i], src, Integer.class); + System.out.println("char " + i + " " + c); + // Low. + byteArray[2 * i] = (byte) (c & 0x0ff); @@ -1020,7 +1084,7 @@ + int i = 0; + int c = 0; + while (((byte) c) != 0) { -+ c = parseCall(args[1 + i], Integer.class); ++ c = parseCall(args[1 + i], src, Integer.class); + byteArray[i] = (byte) c; + i++; + if (i == byteArray.length) { @@ -1049,17 +1113,17 @@ + write(reference, "ExceptionClear"); + } else if (message.startsWith("DeleteGlobalRef")) { + String[] args = message.split(" "); -+ Integer id = parseCall(args[1], Integer.class); ++ Integer id = parseCall(args[1], src, Integer.class); + store.unreference(id); + write(reference, "DeleteGlobalRef"); + } else if (message.startsWith("DeleteLocalRef")) { + String[] args = message.split(" "); -+ Integer id = parseCall(args[1], Integer.class); ++ Integer id = parseCall(args[1], src, Integer.class); + store.unreference(id); + write(reference, "DeleteLocalRef"); + } else if (message.startsWith("NewGlobalRef")) { + String[] args = message.split(" "); -+ Integer id = parseCall(args[1], Integer.class); ++ Integer id = parseCall(args[1], src, Integer.class); + store.reference(store.getObject(id)); + write(reference, "NewGlobalRef " + id); + } @@ -1078,8 +1142,8 @@ +} diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/PluginAppletViewer.java openjdk/jdk/src/share/classes/sun/applet/PluginAppletViewer.java --- openjdk.orig/jdk/src/share/classes/sun/applet/PluginAppletViewer.java 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/src/share/classes/sun/applet/PluginAppletViewer.java 2008-09-04 17:01:38.000000000 -0400 -@@ -0,0 +1,1416 @@ ++++ openjdk/jdk/src/share/classes/sun/applet/PluginAppletViewer.java 2008-09-15 16:22:07.000000000 -0400 +@@ -0,0 +1,1439 @@ + /* + * Copyright 1995-2004 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -1297,6 +1361,25 @@ + } catch (IOException ioe) { + ioe.printStackTrace(); + } ++ ++ // Wait for a maximum of 10 seconds for the panel to initialize ++ // (happens in a separate thread) ++ Applet a; ++ int maxSleepTime = 10000; ++ int sleepTime = 0; ++ while ((a = panel.getApplet()) == null && sleepTime < maxSleepTime) { ++ try { ++ Thread.sleep(100); ++ sleepTime += 100; ++ PluginDebug.debug("Waiting for applet to initialize... "); ++ } catch (InterruptedException ie) { ++ // ignore ++ } ++ } ++ ++ // Applet initialized. Find out it's classloader and add it to the list ++ PluginAppletSecurityContext.classLoaders.put(Integer.toString(identifier), a.getClass().getClassLoader()); ++ + } + + /** @@ -1405,13 +1488,13 @@ + } + } + -+ PluginDebug.debug ("Looking for object " + o + " panel is " + panel.getClass()); ++ System.err.println ("Looking for object " + o + " panel is " + panel.getClass()); + PluginAppletSecurityContext.contexts.get(0).store.reference(o); -+ PluginDebug.debug ("WRITING 1: " + "context 0 reference " + reference + " GetJavaObject " ++ System.err.println ("WRITING 1: " + "context 0 reference " + reference + " GetJavaObject " + + PluginAppletSecurityContext.contexts.get(0).store.getIdentifier(o)); + PluginMain.write("context 0 reference " + reference + " GetJavaObject " + + PluginAppletSecurityContext.contexts.get(0).store.getIdentifier(o)); -+ PluginDebug.debug ("WRITING 1 DONE"); ++ System.err.println ("WRITING 1 DONE"); + } + } + @@ -2278,193 +2361,197 @@ + PluginAppletViewerFactory factory) + throws IOException + { -+ // <OBJECT> <EMBED> tag flags -+ boolean isAppletTag = false; -+ boolean isObjectTag = false; -+ boolean isEmbedTag = false; -+ -+ // warning messages -+ String requiresNameWarning = amh.getMessage("parse.warning.requiresname"); -+ String paramOutsideWarning = amh.getMessage("parse.warning.paramoutside"); -+ String appletRequiresCodeWarning = amh.getMessage("parse.warning.applet.requirescode"); -+ String appletRequiresHeightWarning = amh.getMessage("parse.warning.applet.requiresheight"); -+ String appletRequiresWidthWarning = amh.getMessage("parse.warning.applet.requireswidth"); -+ String objectRequiresCodeWarning = amh.getMessage("parse.warning.object.requirescode"); -+ String objectRequiresHeightWarning = amh.getMessage("parse.warning.object.requiresheight"); -+ String objectRequiresWidthWarning = amh.getMessage("parse.warning.object.requireswidth"); -+ String embedRequiresCodeWarning = amh.getMessage("parse.warning.embed.requirescode"); -+ String embedRequiresHeightWarning = amh.getMessage("parse.warning.embed.requiresheight"); -+ String embedRequiresWidthWarning = amh.getMessage("parse.warning.embed.requireswidth"); -+ String appNotLongerSupportedWarning = amh.getMessage("parse.warning.appnotLongersupported"); -+ -+ java.net.URLConnection conn = url.openConnection(); -+ /* The original URL may have been redirected - this -+ * sets it to whatever URL/codebase we ended up getting -+ */ -+ url = conn.getURL(); -+ -+ int ydisp = 1; -+ Hashtable atts = null; -+ -+ while(true) { -+ c = in.read(); -+ if (c == -1) -+ break; -+ -+ if (c == '<') { -+ c = in.read(); -+ if (c == '/') { -+ c = in.read(); -+ String nm = scanIdentifier(in); -+ if (nm.equalsIgnoreCase("applet") || -+ nm.equalsIgnoreCase("object") || -+ nm.equalsIgnoreCase("embed")) { -+ -+ // We can't test for a code tag until </OBJECT> -+ // because it is a parameter, not an attribute. -+ if(isObjectTag) { -+ if (atts.get("code") == null && atts.get("object") == null) { -+ statusMsgStream.println(objectRequiresCodeWarning); -+ atts = null; -+ } -+ } -+ -+ if (atts != null) { -+ // XXX 5/18 In general this code just simply -+ // shouldn't be part of parsing. It's presence -+ // causes things to be a little too much of a -+ // hack. -+ factory.createAppletViewer(identifier, handle, x, y, url, atts); -+ x += XDELTA; -+ y += YDELTA; -+ // make sure we don't go too far! -+ Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); -+ if ((x > d.width - 300) || (y > d.height - 300)) { -+ x = 0; -+ y = 2 * ydisp * YDELTA; -+ ydisp++; -+ } -+ } -+ atts = null; -+ isAppletTag = false; -+ isObjectTag = false; -+ isEmbedTag = false; -+ } -+ } -+ else { -+ String nm = scanIdentifier(in); -+ if (nm.equalsIgnoreCase("param")) { -+ Hashtable t = scanTag(in); -+ String att = (String)t.get("name"); -+ if (att == null) { -+ statusMsgStream.println(requiresNameWarning); -+ } else { -+ String val = (String)t.get("value"); -+ if (val == null) { -+ statusMsgStream.println(requiresNameWarning); -+ } else if (atts != null) { -+ atts.put(att.toLowerCase(), val); -+ } else { -+ statusMsgStream.println(paramOutsideWarning); -+ } -+ } -+ } -+ else if (nm.equalsIgnoreCase("applet")) { -+ isAppletTag = true; -+ atts = scanTag(in); -+ -+ // If there is a classid present, transform it to code tag -+ if (atts.get("code") == null && atts.get("classid") != null && -+ ((String) atts.get("classid")).startsWith("java:")) { -+ //skip "java:" -+ atts.put("code", ((String) atts.get("classid")).substring(5)); -+ } -+ -+ if (atts.get("code") == null && atts.get("object") == null) { -+ statusMsgStream.println(appletRequiresCodeWarning); -+ atts = null; -+ } else if (atts.get("width") == null) { -+ statusMsgStream.println(appletRequiresWidthWarning); -+ atts = null; -+ } else if (atts.get("height") == null) { -+ statusMsgStream.println(appletRequiresHeightWarning); -+ atts = null; -+ } -+ } -+ else if (nm.equalsIgnoreCase("object")) { -+ isObjectTag = true; -+ atts = scanTag(in); -+ -+ // If there is a classid present, transform it to code tag -+ if (atts.get("code") == null && atts.get("classid") != null && -+ ((String) atts.get("classid")).startsWith("java:")) { -+ //skip "java:" -+ atts.put("code", ((String) atts.get("classid")).substring(5)); -+ } -+ -+ // The <OBJECT> attribute codebase isn't what -+ // we want when not dealing with jars. If its -+ // defined, remove it in that case. -+ if(atts.get("archive") == null && atts.get("codebase") != null) { -+ atts.remove("codebase"); -+ } -+ -+ if (atts.get("width") == null) { -+ statusMsgStream.println(objectRequiresWidthWarning); -+ atts = null; -+ } else if (atts.get("height") == null) { -+ statusMsgStream.println(objectRequiresHeightWarning); -+ atts = null; -+ } -+ } -+ else if (nm.equalsIgnoreCase("embed")) { -+ isEmbedTag = true; -+ atts = scanTag(in); -+ -+ // If there is a classid present, transform it to code tag -+ if (atts.get("code") == null && atts.get("classid") != null && -+ ((String) atts.get("classid")).startsWith("java:")) { -+ //skip "java:" -+ atts.put("code", ((String) atts.get("classid")).substring(5)); -+ } -+ -+ if (atts.get("code") == null && atts.get("object") == null) { -+ statusMsgStream.println(embedRequiresCodeWarning); -+ atts = null; -+ } else if (atts.get("width") == null) { -+ statusMsgStream.println(embedRequiresWidthWarning); -+ atts = null; -+ } else if (atts.get("height") == null) { -+ statusMsgStream.println(embedRequiresHeightWarning); -+ atts = null; -+ } -+ } -+ else if (nm.equalsIgnoreCase("app")) { -+ statusMsgStream.println(appNotLongerSupportedWarning); -+ Hashtable atts2 = scanTag(in); -+ nm = (String)atts2.get("class"); -+ if (nm != null) { -+ atts2.remove("class"); -+ atts2.put("code", nm + ".class"); -+ } -+ nm = (String)atts2.get("src"); -+ if (nm != null) { -+ atts2.remove("src"); -+ atts2.put("codebase", nm); -+ } -+ if (atts2.get("width") == null) { -+ atts2.put("width", "100"); -+ } -+ if (atts2.get("height") == null) { -+ atts2.put("height", "100"); -+ } -+ printTag(statusMsgStream, atts2); -+ statusMsgStream.println(); -+ } -+ } -+ } -+ } -+ in.close(); ++ // <OBJECT> <EMBED> tag flags ++ boolean isAppletTag = false; ++ boolean isObjectTag = false; ++ boolean isEmbedTag = false; ++ ++ // warning messages ++ String requiresNameWarning = amh.getMessage("parse.warning.requiresname"); ++ String paramOutsideWarning = amh.getMessage("parse.warning.paramoutside"); ++ String appletRequiresCodeWarning = amh.getMessage("parse.warning.applet.requirescode"); ++ String appletRequiresHeightWarning = amh.getMessage("parse.warning.applet.requiresheight"); ++ String appletRequiresWidthWarning = amh.getMessage("parse.warning.applet.requireswidth"); ++ String objectRequiresCodeWarning = amh.getMessage("parse.warning.object.requirescode"); ++ String objectRequiresHeightWarning = amh.getMessage("parse.warning.object.requiresheight"); ++ String objectRequiresWidthWarning = amh.getMessage("parse.warning.object.requireswidth"); ++ String embedRequiresCodeWarning = amh.getMessage("parse.warning.embed.requirescode"); ++ String embedRequiresHeightWarning = amh.getMessage("parse.warning.embed.requiresheight"); ++ String embedRequiresWidthWarning = amh.getMessage("parse.warning.embed.requireswidth"); ++ String appNotLongerSupportedWarning = amh.getMessage("parse.warning.appnotLongersupported"); ++ ++ java.net.URLConnection conn = url.openConnection(); ++ /* The original URL may have been redirected - this ++ * sets it to whatever URL/codebase we ended up getting ++ */ ++ url = conn.getURL(); ++ ++ int ydisp = 1; ++ Hashtable atts = null; ++ ++ while(true) { ++ c = in.read(); ++ if (c == -1) ++ break; ++ ++ if (c == '<') { ++ c = in.read(); ++ if (c == '/') { ++ c = in.read(); ++ String nm = scanIdentifier(in); ++ if (nm.equalsIgnoreCase("applet") || ++ nm.equalsIgnoreCase("object") || ++ nm.equalsIgnoreCase("embed")) { ++ ++ // We can't test for a code tag until </OBJECT> ++ // because it is a parameter, not an attribute. ++ if(isObjectTag) { ++ if (atts.get("code") == null && atts.get("object") == null) { ++ statusMsgStream.println(objectRequiresCodeWarning); ++ atts = null; ++ } ++ } ++ ++ if (atts != null) { ++ // XXX 5/18 In general this code just simply ++ // shouldn't be part of parsing. It's presence ++ // causes things to be a little too much of a ++ // hack. ++ factory.createAppletViewer(identifier, handle, x, y, url, atts); ++ x += XDELTA; ++ y += YDELTA; ++ // make sure we don't go too far! ++ Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); ++ if ((x > d.width - 300) || (y > d.height - 300)) { ++ x = 0; ++ y = 2 * ydisp * YDELTA; ++ ydisp++; ++ } ++ } ++ atts = null; ++ isAppletTag = false; ++ isObjectTag = false; ++ isEmbedTag = false; ++ } ++ } ++ else { ++ String nm = scanIdentifier(in); ++ if (nm.equalsIgnoreCase("param")) { ++ Hashtable t = scanTag(in); ++ String att = (String)t.get("name"); ++ if (att == null) { ++ statusMsgStream.println(requiresNameWarning); ++ } else { ++ String val = (String)t.get("value"); ++ if (val == null) { ++ statusMsgStream.println(requiresNameWarning); ++ } else if (atts != null) { ++ atts.put(att.toLowerCase(), val); ++ } else { ++ statusMsgStream.println(paramOutsideWarning); ++ } ++ } ++ } ++ else if (nm.equalsIgnoreCase("applet")) { ++ isAppletTag = true; ++ atts = scanTag(in); ++ ++ // If there is a classid present, transform it to code tag ++ if (atts.get("code") == null && atts.get("classid") != null && ++ ((String) atts.get("classid")).startsWith("java:")) { ++ //skip "java:" ++ atts.put("code", ((String) atts.get("classid")).substring(5)); ++ } ++ ++ if (atts.get("code") == null && atts.get("object") == null) { ++ statusMsgStream.println(appletRequiresCodeWarning); ++ atts = null; ++ } ++ ++ if (atts.get("width") == null) { ++ atts.put("width", "100%"); ++ } ++ ++ if (atts.get("height") == null) { ++ atts.put("height", "100%"); ++ } ++ } ++ else if (nm.equalsIgnoreCase("object")) { ++ isObjectTag = true; ++ atts = scanTag(in); ++ ++ // If there is a classid present, transform it to code tag ++ if (atts.get("code") == null && atts.get("classid") != null && ++ ((String) atts.get("classid")).startsWith("java:")) { ++ //skip "java:" ++ atts.put("code", ((String) atts.get("classid")).substring(5)); ++ } ++ ++ // The <OBJECT> attribute codebase isn't what ++ // we want when not dealing with jars. If its ++ // defined, remove it in that case. ++ if(atts.get("archive") == null && atts.get("codebase") != null) { ++ atts.remove("codebase"); ++ } ++ ++ if (atts.get("width") == null) { ++ atts.put("width", "100%"); ++ } ++ ++ if (atts.get("height") == null) { ++ atts.put("height", "100%"); ++ } ++ } ++ else if (nm.equalsIgnoreCase("embed")) { ++ isEmbedTag = true; ++ atts = scanTag(in); ++ ++ // If there is a classid present, transform it to code tag ++ if (atts.get("code") == null && atts.get("classid") != null && ++ ((String) atts.get("classid")).startsWith("java:")) { ++ //skip "java:" ++ atts.put("code", ((String) atts.get("classid")).substring(5)); ++ } ++ ++ if (atts.get("code") == null && atts.get("object") == null) { ++ statusMsgStream.println(embedRequiresCodeWarning); ++ atts = null; ++ } ++ ++ if (atts.get("width") == null) { ++ atts.put("width", "100%"); ++ } ++ ++ if (atts.get("height") == null) { ++ atts.put("height", "100%"); ++ } ++ } ++ else if (nm.equalsIgnoreCase("app")) { ++ statusMsgStream.println(appNotLongerSupportedWarning); ++ Hashtable atts2 = scanTag(in); ++ nm = (String)atts2.get("class"); ++ if (nm != null) { ++ atts2.remove("class"); ++ atts2.put("code", nm + ".class"); ++ } ++ nm = (String)atts2.get("src"); ++ if (nm != null) { ++ atts2.remove("src"); ++ atts2.put("codebase", nm); ++ } ++ if (atts2.get("width") == null) { ++ atts2.put("width", "100%"); ++ } ++ if (atts2.get("height") == null) { ++ atts2.put("height", "100%"); ++ } ++ printTag(statusMsgStream, atts2); ++ statusMsgStream.println(); ++ } ++ } ++ } ++ } ++ in.close(); + } + + /** @@ -2498,8 +2585,8 @@ + } diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/PluginCallRequest.java openjdk/jdk/src/share/classes/sun/applet/PluginCallRequest.java --- openjdk.orig/jdk/src/share/classes/sun/applet/PluginCallRequest.java 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/src/share/classes/sun/applet/PluginCallRequest.java 2008-07-20 22:33:36.000000000 -0400 -@@ -0,0 +1,54 @@ ++++ openjdk/jdk/src/share/classes/sun/applet/PluginCallRequest.java 2008-09-15 16:22:07.000000000 -0400 +@@ -0,0 +1,56 @@ +/* PluginCallRequest -- represent Java-to-JavaScript requests + Copyright (C) 2008 Red Hat + @@ -2553,10 +2640,12 @@ + } + + public abstract void parseReturn(String message); ++ ++ public abstract boolean serviceable(String message); +} diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/PluginDebug.java openjdk/jdk/src/share/classes/sun/applet/PluginDebug.java --- openjdk.orig/jdk/src/share/classes/sun/applet/PluginDebug.java 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/src/share/classes/sun/applet/PluginDebug.java 2008-08-15 15:19:49.000000000 -0400 ++++ openjdk/jdk/src/share/classes/sun/applet/PluginDebug.java 2008-09-15 16:21:47.000000000 -0400 @@ -0,0 +1,13 @@ +package sun.applet; + @@ -2573,8 +2662,8 @@ +} diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/PluginException.java openjdk/jdk/src/share/classes/sun/applet/PluginException.java --- openjdk.orig/jdk/src/share/classes/sun/applet/PluginException.java 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/src/share/classes/sun/applet/PluginException.java 2008-09-04 17:01:38.000000000 -0400 -@@ -0,0 +1,12 @@ ++++ openjdk/jdk/src/share/classes/sun/applet/PluginException.java 2008-09-15 16:22:08.000000000 -0400 +@@ -0,0 +1,14 @@ +package sun.applet; + +public class PluginException extends Exception { @@ -2583,14 +2672,16 @@ + t.printStackTrace(); + this.setStackTrace(t.getStackTrace()); + ++ PluginAppletSecurityContext.contexts.get(0).store.dump(); ++ + String message = "instance " + instance + " reference " + reference + " Error " + t.getMessage(); + PluginMain.write(message); + } +} diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/PluginMain.java openjdk/jdk/src/share/classes/sun/applet/PluginMain.java --- openjdk.orig/jdk/src/share/classes/sun/applet/PluginMain.java 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/src/share/classes/sun/applet/PluginMain.java 2008-09-04 17:01:38.000000000 -0400 -@@ -0,0 +1,485 @@ ++++ openjdk/jdk/src/share/classes/sun/applet/PluginMain.java 2008-09-15 16:22:08.000000000 -0400 +@@ -0,0 +1,533 @@ +/* + * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -2629,6 +2720,7 @@ +class RequestQueue { + PluginCallRequest head = null; + PluginCallRequest tail = null; ++ private int size = 0; + + void post(PluginCallRequest request) { + if (head == null) { @@ -2639,6 +2731,8 @@ + tail = request; + tail.next = null; + } ++ ++ size++; + } + + PluginCallRequest pop() { @@ -2648,8 +2742,15 @@ + PluginCallRequest ret = head; + head = head.next; + ret.next = null; ++ ++ size--; ++ + return ret; + } ++ ++ int size() { ++ return size; ++ } +} + +/** @@ -2850,15 +2951,23 @@ + + String rest = ""; + int reference = -1; -+ -+ rest = st.nextToken(); ++ String src = null; ++ ++ String potentialReference = st.hasMoreTokens() ? st.nextToken() : ""; + + // if the next token is reference, read it, else reset "rest" -+ if (rest.equals("reference")) { ++ if (potentialReference.equals("reference")) { + reference = Integer.parseInt(st.nextToken()); -+ rest = ""; + } else { -+ rest += " "; ++ rest += potentialReference + " "; ++ } ++ ++ String potentialSrc = st.hasMoreTokens() ? st.nextToken() : ""; ++ ++ if (potentialSrc.equals("src")) { ++ src = st.nextToken(); ++ } else { ++ rest += potentialSrc + " "; + } + + while (st.hasMoreElements()) { @@ -2870,7 +2979,7 @@ + + try { + -+ System.err.println("Breakdown -- type: " + type + " identifier: " + identifier + " reference: " + reference + " rest: " + rest); ++ System.err.println("Breakdown -- type: " + type + " identifier: " + identifier + " reference: " + reference + " src: " + src + " rest: " + rest); + + if (rest.contains("JavaScriptGetWindow") + || rest.contains("JavaScriptGetMember") @@ -2890,7 +2999,7 @@ + PluginAppletViewer.handleMessage(identifier, reference, rest); + else if (type.equals("context")) { + PluginDebug.debug("Sending to PASC: " + identifier + "/" + reference + " and " + rest); -+ PluginAppletSecurityContext.handleMessage(identifier, reference, rest); ++ PluginAppletSecurityContext.handleMessage(identifier, src, reference, rest); + } + } catch (Exception e) { + throw new PluginException(identifier, reference, e); @@ -2974,6 +3083,36 @@ + synchronized(queue) { + PluginDebug.debug ("DISPATCHCALLREQUESTS 2"); + PluginCallRequest request = queue.pop(); ++ ++ // make sure we give the message to the right request ++ // in the queue.. for the love of God, MAKE SURE! ++ ++ // first let's be efficient.. if there was only one ++ // request in queue, we're already set ++ if (queue.size() != 0) { ++ ++ int size = queue.size(); ++ int count = 0; ++ ++ while (!request.serviceable(message)) { ++ ++ // something is very wrong.. we have a message to ++ // process, but no one to service it ++ if (count >= size) { ++ throw new RuntimeException("Unable to find processor for message " + message); ++ } ++ ++ // post request at the end of the queue ++ queue.post(request); ++ ++ // Look at the next request ++ request = queue.pop(); ++ ++ count++; ++ } ++ ++ } ++ + PluginDebug.debug ("DISPATCHCALLREQUESTS 3"); + if (request != null) { + PluginDebug.debug ("DISPATCHCALLREQUESTS 5"); @@ -3078,7 +3217,7 @@ +} diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/PluginMessageConsumer.java openjdk/jdk/src/share/classes/sun/applet/PluginMessageConsumer.java --- openjdk.orig/jdk/src/share/classes/sun/applet/PluginMessageConsumer.java 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/src/share/classes/sun/applet/PluginMessageConsumer.java 2008-09-04 17:01:39.000000000 -0400 ++++ openjdk/jdk/src/share/classes/sun/applet/PluginMessageConsumer.java 2008-09-15 16:21:47.000000000 -0400 @@ -0,0 +1,49 @@ +package sun.applet; + @@ -3131,7 +3270,7 @@ +} diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/PluginMessageHandlerWorker.java openjdk/jdk/src/share/classes/sun/applet/PluginMessageHandlerWorker.java --- openjdk.orig/jdk/src/share/classes/sun/applet/PluginMessageHandlerWorker.java 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/src/share/classes/sun/applet/PluginMessageHandlerWorker.java 2008-08-19 15:47:52.000000000 -0400 ++++ openjdk/jdk/src/share/classes/sun/applet/PluginMessageHandlerWorker.java 2008-09-15 16:21:47.000000000 -0400 @@ -0,0 +1,59 @@ +package sun.applet; + @@ -3194,7 +3333,7 @@ +} diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/PluginObjectStore.java openjdk/jdk/src/share/classes/sun/applet/PluginObjectStore.java --- openjdk.orig/jdk/src/share/classes/sun/applet/PluginObjectStore.java 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/src/share/classes/sun/applet/PluginObjectStore.java 2008-08-13 16:37:22.000000000 -0400 ++++ openjdk/jdk/src/share/classes/sun/applet/PluginObjectStore.java 2008-09-15 16:21:47.000000000 -0400 @@ -0,0 +1,119 @@ +/* PluginObjectStore -- manage identifier-to-object mapping + Copyright (C) 2008 Red Hat @@ -3317,7 +3456,7 @@ + diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/TestEnv.java openjdk/jdk/src/share/classes/sun/applet/TestEnv.java --- openjdk.orig/jdk/src/share/classes/sun/applet/TestEnv.java 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/src/share/classes/sun/applet/TestEnv.java 2008-07-20 22:33:36.000000000 -0400 ++++ openjdk/jdk/src/share/classes/sun/applet/TestEnv.java 2008-09-15 16:21:47.000000000 -0400 @@ -0,0 +1,172 @@ +/* TestEnv -- test JavaScript-to-Java calls + Copyright (C) 2008 Red Hat @@ -3493,8 +3632,8 @@ +} diff -urN openjdk.orig/jdk/src/share/classes/sun/applet/VoidPluginCallRequest.java openjdk/jdk/src/share/classes/sun/applet/VoidPluginCallRequest.java --- openjdk.orig/jdk/src/share/classes/sun/applet/VoidPluginCallRequest.java 1969-12-31 19:00:00.000000000 -0500 -+++ openjdk/jdk/src/share/classes/sun/applet/VoidPluginCallRequest.java 2008-07-20 22:33:36.000000000 -0400 -@@ -0,0 +1,49 @@ ++++ openjdk/jdk/src/share/classes/sun/applet/VoidPluginCallRequest.java 2008-09-15 16:22:09.000000000 -0400 +@@ -0,0 +1,62 @@ +/* VoidPluginCallRequest -- represent Java-to-JavaScript requests + Copyright (C) 2008 Red Hat + @@ -3543,4 +3682,17 @@ + public void parseReturn(String message) { + done = true; + } ++ ++ /** ++ * Returns whether the given message is serviceable by this object ++ * ++ * @param message The message to service ++ * @return boolean indicating if message is serviceable ++ */ ++ public boolean serviceable(String message) { ++ return message.contains("JavaScriptFinalize") || ++ message.contains("JavaScriptRemoveMember") || ++ message.contains("JavaScriptSetMember") || ++ message.contains("JavaScriptSetSlot"); ++ } +}