--- a/ChangeLog Wed Aug 26 01:14:21 2009 -0400 +++ b/ChangeLog Wed Aug 26 15:06:47 2009 -0400 @@ -1,3 +1,84 @@ 2009-08-26 Deepak Bhole + + * plugin/icedteanp/IcedTeaJavaRequestProcessor.cc + (createJavaObjectFromVariant): Add conditional compilation blocks to + handle new API along with old. Call renamed newObjectWithConstructor + function. + (newObject): New function. Creates an object based on the most optimum + cost with arbitrary arguments. + (newObjectWithConstructor): Renamed from newObject(). Also, take source as + an argument to provide to Java. + * plugin/icedteanp/IcedTeaJavaRequestProcessor.h: Change as per above .cc + file changes. + * plugin/icedteanp/IcedTeaNPPlugin.cc: Include XPCOM specific headers only + if xulrunner version is < 1.9.2. Instantiate internal Mozilla objects only + if xulrunner < 1.9.2. + (GCJ_New): Correctly account for documentbase length when allocating tag + memory to prevent corruption. + (GCJ_Destroy): Remove old instance mappings when destroyed. + (GCJ_GetJavaClass): Remove unused method. + (get_cookie_info): Change object signature to include length result. Based + on xulrunner version, either use internal Mozilla API for fetching cookie + info, or use NPN_GetValueForURL. + (plugin_get_documentbase): Define for when xulrunner is >= 1.9.2. + (consume_message): Deal with single proxy URL rather than components. + Update to handle when xulrunner is >= 1.9.2 + (get_proxy_info): Change signature to deal with single url rather than + components. Use NPN_GetValueForURL if xulrunner is >= 1.9.2. + (NP_Initialize): Add pointers for getvalueforurl and setvalueforurl in the + NPPluginFuncs table. Also, handle case for when browser provides the + plugin .so name as the link location rather than target location. + * plugin/icedteanp/IcedTeaNPPlugin.h: Include XPCOM specific headers only + if xulrunner version is < 1.9.2. + * plugin/icedteanp/IcedTeaPluginRequestProcessor.cc + (eval): Use the new NPN_PluginThreadAsynCcall function to dispatch events + to main thread asynchronously. + (call): Same. + (setMember): Same. + (getMember): Same. + (storeVariantInJava): Handle changed API when xulrunner >= 1.9.2 + (_setMember): Account for changes in the way that the callerpacks + arguments. + (_getMember): Same. + (_call): Same. + (_eval): Same. + * plugin/icedteanp/IcedTeaPluginRequestProcessor.h: Include Mozilla + specific headers only if xulrunner is < 1.9.2. Remove old ThreadData + struct and add new AyncCallThreadData struct that contains results and + arguments. + * plugin/icedteanp/IcedTeaPluginUtils.cc + (getSourceFromInstance): Provide null source location due to lack of a + secure way to get documentbase. + (printNPVariant): Account for change API in xulrunner 1.9.2. + (NPVariantToString): Same. + * plugin/icedteanp/IcedTeaPluginUtils.h: Include Mozilla specific headers + only if xulrunner is < 1.9.2. + * plugin/icedteanp/IcedTeaScriptablePluginObject.cc + (invoke): Pass exception over to JS engine. + (construct): Implement object construction. + * plugin/icedteanp/IcedTeaScriptablePluginObject.h: Include Mozilla + specific headers only if xulrunner is < 1.9.2. + * plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java + (getMatchingConstructor): New method, returns a matching constructor based + on arguments. + (getMatchingConstructors): New helper method for getMatchingConstructor. + * plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java + (handleMessage): Handle new type of call, "NewObjectWithConstructor". + (checkPermission): Disable checks for the time being, as NPRuntime does + not allow cross-site calling anyway. + * plugin/icedteanp/java/sun/applet/PluginAppletViewer.java + (setStatus): Remove newlines from status messages. + * plugin/icedteanp/sun/applet/PluginCookieInfoRequest.java + (parseReturn): Store cookie info as a string rather than a list of + HttpCookie objects. + (getObject): Return the new cookie string. + * plugin/icedteanp/sun/applet/PluginCookieManager.java: New file, extends + CookieManager as is set as the default cookie manager for the plugin. + * plugin/icedteanp/sun/applet/PluginCookieStore.java : Deleted. New design + uses a custom cookiemanager rather than just a custom store. + * plugin/icedteanp/sun/applet/PluginMain.java + (init): Wire in the new cookie manager. + 2009-08-26 Deepak Bhole * plugin/icedtea/sun/applet/PluginAppletViewer.java --- a/plugin/icedteanp/IcedTeaJavaRequestProcessor.cc Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/IcedTeaJavaRequestProcessor.cc Wed Aug 26 15:06:47 2009 -0400 @@ -122,7 +122,6 @@ JavaRequestProcessor::newMessageOnBus(co { result_ready = true; // nothing else to do } else if ((message_parts->at(4) == "CallMethod") || - (message_parts->at(4) == "CallStaticMethod")) { @@ -656,8 +655,11 @@ JavaRequestProcessor::createJavaObjectFr else if (NPVARIANT_IS_STRING(variant)) { className = "java.lang.String"; - +#if MOZILLA_VERSION_COLLAPSED < 1090200 stringArg += NPVARIANT_TO_STRING(variant).utf8characters; +#else + stringArg += NPVARIANT_TO_STRING(variant).UTF8Characters; +#endif } else { alreadyCreated = true; } @@ -703,7 +705,7 @@ JavaRequestProcessor::createJavaObjectFr std::string arg = std::string(); arg.append(*(java_result->return_string)); args.push_back(arg); - java_result = java_request.newObject("[System]", jsObjectClassID, jsObjectConstructorID, args); + java_result = java_request.newObjectWithConstructor("[System]", jsObjectClassID, jsObjectConstructorID, args); if (java_result->error_occurred) { printf("Unable to create requested object\n"); @@ -808,7 +810,46 @@ JavaRequestProcessor::getObjectClass(std } JavaResultData* -JavaRequestProcessor::newObject(std::string source, std::string objectID, +JavaRequestProcessor::newObject(std::string source, std::string classID, + const NPVariant* args, int argCount) +{ + JavaRequestProcessor* java_request; + std::string message = std::string(); + + this->instance = 0; // context is always 0 (needed for java-side backwards compat.) + this->reference = IcedTeaPluginUtilities::getReference(); + + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, source, &message); + message += " NewObject "; + message += classID; + message += " "; + + // First, we need to load the arguments into the java-side table + for (int i=0; i < argCount; i++) { + int objectID = createJavaObjectFromVariant(args[i]); + if (objectID == 0) + { + result->error_occurred = true; + result->error_msg->append("Unable to create arguments"); + return result; + } + + char* id = (char*) malloc(sizeof(char)*32); + sprintf(id, "%d", objectID); + message += id; + message += " "; + free(id); + } + + postAndWaitForResponse(message); + + IcedTeaPluginUtilities::releaseReference(); + + return result; +} + +JavaResultData* +JavaRequestProcessor::newObjectWithConstructor(std::string source, std::string classID, std::string methodID, std::vector args) { @@ -819,8 +860,8 @@ JavaRequestProcessor::newObject(std::str this->reference = IcedTeaPluginUtilities::getReference(); IcedTeaPluginUtilities::constructMessagePrefix(0, reference, source, &message); - message += " NewObject "; - message += objectID; + message += " NewObjectWithConstructor "; + message += classID; message += " "; message += methodID; message += " "; @@ -980,3 +1021,4 @@ JavaRequestProcessor::getAppletObjectIns return result; } + --- a/plugin/icedteanp/IcedTeaJavaRequestProcessor.h Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/IcedTeaJavaRequestProcessor.h Wed Aug 26 15:06:47 2009 -0400 @@ -171,9 +171,14 @@ class JavaRequestProcessor : BusSubscrib /* Returns the class of the given object */ JavaResultData* getObjectClass(std::string objectID); - /* Creates a new object */ + /* Creates a new object with choosable constructor */ JavaResultData* newObject(std::string source, - std::string objectID, std::string methodID, + std::string classID, + const NPVariant* args, int numArgs); + + /* Creates a new object when constructor is undetermined */ + JavaResultData* newObjectWithConstructor(std::string source, std::string classID, + std::string methodID, std::vector args); /* Returns the class ID */ --- a/plugin/icedteanp/IcedTeaNPPlugin.cc Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/IcedTeaNPPlugin.cc Wed Aug 26 15:06:47 2009 -0400 @@ -47,12 +47,15 @@ exception statement from your version. * #include #include +#if MOZILLA_VERSION_COLLAPSED < 1090200 // Documentbase retrieval includes. #include #include #include +#endif // API's into Mozilla +#if MOZILLA_VERSION_COLLAPSED < 1090200 #include #include #include @@ -66,9 +69,10 @@ exception statement from your version. * #include #include #include +#endif // Liveconnect extension - #include "IcedTeaScriptablePluginObject.h" +#include "IcedTeaScriptablePluginObject.h" #include "IcedTeaNPPlugin.h" // Error reporting macros. @@ -132,8 +136,10 @@ exception statement from your version. * #define FAILURE_MESSAGE "gcjwebplugin error: Failed to run %s." \ " For more detail rerun \"firefox -g\" in a terminal window." +#if MOZILLA_VERSION_COLLAPSED < 1090200 // Documentbase retrieval required definition. static NS_DEFINE_IID (kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID); +#endif // Data directory for plugin. static gchar* data_directory = NULL; @@ -180,14 +186,14 @@ PluginRequestProcessor* plugin_req_proc; // Sends messages to Java over the bus JavaMessageSender* java_req_proc; -GQuark ITNP_PLUGIN_ERROR = g_quark_from_string("IcedTeaNPPlugin"); - +#if MOZILLA_VERSION_COLLAPSED < 1090200 // Documentbase retrieval type-punning union. typedef union { void** void_field; nsIPluginTagInfo2** info_field; } info_union; +#endif // Static instance helper functions. // Have the browser allocate a new GCJPluginData structure. @@ -211,8 +217,8 @@ static void plugin_stop_appletviewer (); // Uninitialize GCJPluginData structure static void plugin_data_destroy (NPP instance); -NS_IMETHODIMP get_cookie_info(const char* siteAddr, char** cookieString); -void get_proxy_info(const char* siteAddr, char** proxy_scheme, char** proxy_host, char** proxy_port, GError *error); +NPError get_cookie_info(const char* siteAddr, char** cookieString, uint32_t* len); +NPError get_proxy_info(const char* siteAddr, char** proxy, uint32_t* len); void decode_url(const gchar* url, gchar** decoded_url); void consume_message(gchar* message); void start_jvm_if_needed(); @@ -336,7 +342,7 @@ GCJ_New (NPMIMEType pluginType, NPP inst // Send applet tag message to appletviewer. applet_tag = plugin_create_applet_tag (argc, argn, argv); - tag_message = (gchar*) malloc(strlen(applet_tag)*sizeof(gchar) + 1024); + tag_message = (gchar*) malloc(strlen(applet_tag)*sizeof(gchar) + strlen(documentbase)*sizeof(gchar) + 32); g_sprintf(tag_message, "instance %d tag %s %s", instance_counter, documentbase, applet_tag); //plugin_send_message_to_appletviewer (data, data->instance_string); @@ -636,6 +642,11 @@ GCJ_Destroy (NPP instance, NPSavedData** plugin_data_destroy (instance); } + int id = get_id_from_instance(instance); + + g_hash_table_remove(instance_to_id_map, instance); + g_hash_table_remove(id_to_instance_map, GINT_TO_POINTER(id)); + PLUGIN_DEBUG_0ARG ("GCJ_Destroy return\n"); return NPERR_NO_ERROR; @@ -844,31 +855,22 @@ GCJ_URLNotify (NPP instance, const char* PLUGIN_DEBUG_0ARG ("GCJ_URLNotify return\n"); } -jref -GCJ_GetJavaClass (void) -{ - PLUGIN_DEBUG_0ARG ("GCJ_GetJavaClass\n"); - - PLUGIN_DEBUG_0ARG ("GCJ_GetJavaClass return\n"); - - return 0; -} - -NS_IMETHODIMP -get_cookie_info(const char* siteAddr, char** cookieString) -{ +NPError +get_cookie_info(const char* siteAddr, char** cookieString, uint32_t* len) +{ +#if MOZILLA_VERSION_COLLAPSED < 1090200 nsresult rv; nsCOMPtr sec_man = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); if (!sec_man) { - return NS_ERROR_FAILURE; + return NPERR_GENERIC_ERROR; } nsCOMPtr io_svc = do_GetService("@mozilla.org/network/io-service;1", &rv); if (NS_FAILED(rv) || !io_svc) { - return NS_ERROR_FAILURE; + return NPERR_GENERIC_ERROR; } nsCOMPtr uri; @@ -877,18 +879,44 @@ get_cookie_info(const char* siteAddr, ch nsCOMPtr cookie_svc = do_GetService("@mozilla.org/cookieService;1", &rv); if (NS_FAILED(rv) || !cookie_svc) { - return NS_ERROR_FAILURE; + return NPERR_GENERIC_ERROR; } rv = cookie_svc->GetCookieString(uri, NULL, cookieString); if (NS_FAILED(rv) || !*cookieString) { - return NS_ERROR_FAILURE; + return NPERR_GENERIC_ERROR; } - return NS_OK; -} - +#else + + // getvalueforurl needs an NPP instance. Quite frankly, there is no easy way + // to know which instance needs the information, as applets on Java side can + // be multi-threaded and the thread making a proxy.cookie request cannot be + // easily tracked. + + // Fortunately, XULRunner does not care about the instance as long as it is + // valid. So we just pick the first valid one and use it. Proxy/Cookie + // information is not instance specific anyway, it is URL specific. + + if (browser_functions.getvalueforurl) + { + GHashTableIter iter; + gpointer id, instance; + + g_hash_table_iter_init (&iter, instance_to_id_map); + g_hash_table_iter_next (&iter, &instance, &id); + + return browser_functions.getvalueforurl((NPP) instance, NPNURLVCookie, siteAddr, cookieString, len); + } else + { + return NPERR_GENERIC_ERROR; + } + +#endif + + return NPERR_NO_ERROR; +} // HELPER FUNCTIONS @@ -906,6 +934,8 @@ plugin_data_new (GCJPluginData** data) PLUGIN_DEBUG_0ARG ("plugin_data_new return\n"); } + + // Documentbase retrieval. This function gets the current document's // documentbase. This function relies on browser-private data so it @@ -913,6 +943,7 @@ plugin_data_new (GCJPluginData** data) // browser. We could not find a way to retrieve the documentbase // using the original Netscape plugin API so we use the XPCOM API // instead. +#if MOZILLA_VERSION_COLLAPSED < 1090200 static gchar* plugin_get_documentbase (NPP instance) { @@ -970,8 +1001,56 @@ plugin_get_documentbase (NPP instance) cleanup_done: PLUGIN_DEBUG_0ARG ("plugin_get_documentbase return\n"); + PLUGIN_DEBUG_1ARG("plugin_get_documentbase returning: %s\n", documentbase_copy); return documentbase_copy; } +#else +static gchar* +plugin_get_documentbase (NPP instance) +{ + PLUGIN_DEBUG_0ARG ("plugin_get_documentbase\n"); + + char const* documentbase = NULL; + gchar* documentbase_copy = NULL; + + // FIXME: This method is not ideal, but there are no known NPAPI call + // for this. See thread for more information: + // http://www.mail-archive.com/chromium-dev@googlegroups.com/msg04844.html + + // Additionally, since it is insecure, we cannot use it for making + // security decisions. + NPObject* window; + NPString script = NPString(); + std::string script_str = std::string(); + NPVariant* location = new NPVariant(); + std::string location_str = std::string(); + + browser_functions.getvalue(instance, NPNVWindowNPObject, &window); + script_str += "window.location.href"; + script.UTF8Characters = script_str.c_str(); + script.UTF8Length = script_str.size(); + browser_functions.evaluate(instance, window, &script, location); + + // Strip everything after the last "/" + gchar** parts = g_strsplit (NPVARIANT_TO_STRING(*location).UTF8Characters, "/", -1); + guint parts_sz = g_strv_length (parts); + + for (int i=0; i < parts_sz - 1; i++) + { + location_str += parts[i]; + location_str += "/"; + } + + documentbase_copy = g_strdup (location_str.c_str()); + + // Release references. + cleanup_done: + PLUGIN_DEBUG_0ARG ("plugin_get_documentbase return\n"); + PLUGIN_DEBUG_1ARG("plugin_get_documentbase returning: %s\n", documentbase_copy); + + return documentbase_copy; +} +#endif // This function displays an error message if the appletviewer has not // been installed correctly. @@ -1135,21 +1214,22 @@ void consume_message(gchar* message) { gchar** parts = g_strsplit (message, " ", 3); if (g_str_has_prefix(parts[1], "PluginProxyInfo")) { - gchar* proxy_scheme = (gchar*) malloc(sizeof(gchar)*32); - gchar* proxy_host = (gchar*) malloc(sizeof(gchar)*64); - gchar* proxy_port = (gchar*) malloc(sizeof(gchar)*8); - - GError *error = g_error_new(ITNP_PLUGIN_ERROR, 0, ""); + gchar* proxy; + uint32_t len; gchar* decoded_url = (gchar*) malloc(strlen(parts[2])*sizeof(gchar) + sizeof(gchar)); decode_url(parts[2], &decoded_url); - get_proxy_info(decoded_url, &proxy_scheme, &proxy_host, &proxy_port, error); gchar* proxy_info; + +#if MOZILLA_VERSION_COLLAPSED < 1090200 + proxy = (char*) malloc(sizeof(char)*2048); +#endif + proxy_info = g_strconcat ("plugin PluginProxyInfo ", NULL); - if (error->code == 0) + if (get_proxy_info(decoded_url, &proxy, &len) == NPERR_NO_ERROR) { - proxy_info = g_strconcat (proxy_info, proxy_scheme, " ", proxy_host, " ", proxy_port, NULL); + proxy_info = g_strconcat (proxy_info, proxy, NULL); } PLUGIN_DEBUG_1ARG("Proxy info: %s\n", proxy_info); @@ -1159,22 +1239,21 @@ void consume_message(gchar* message) { decoded_url = NULL; g_free(proxy_info); proxy_info = NULL; - g_free(proxy_scheme); - proxy_scheme = NULL; - g_free(proxy_host); - proxy_host = NULL; - g_free(proxy_port); - proxy_port = NULL; + +#if MOZILLA_VERSION_COLLAPSED < 1090200 + g_free(proxy); + proxy = NULL; +#endif + } else if (g_str_has_prefix(parts[1], "PluginCookieInfo")) { - GError *error = g_error_new(ITNP_PLUGIN_ERROR, 0, ""); - gchar* decoded_url = (gchar*) malloc(strlen(parts[2])*sizeof(gchar) + sizeof(gchar)); decode_url(parts[2], &decoded_url); gchar* cookie_info = g_strconcat ("plugin PluginCookieInfo ", parts[2], " ", NULL); gchar* cookie_string; - if (get_cookie_info(decoded_url, &cookie_string) == NS_OK) + uint32_t len; + if (get_cookie_info(decoded_url, &cookie_string, &len) == NPERR_NO_ERROR) { cookie_info = g_strconcat (cookie_info, cookie_string, NULL); } @@ -1184,8 +1263,6 @@ void consume_message(gchar* message) { g_free(decoded_url); decoded_url = NULL; - g_free(cookie_string); - cookie_string = NULL; g_free(cookie_info); cookie_info = NULL; } @@ -1210,6 +1287,7 @@ int get_id_from_instance(NPP instance) void decode_url(const gchar* url, gchar** decoded_url) { +#if MOZILLA_VERSION_COLLAPSED < 1090200 // There is no GLib function to decode urls, so we fallback to Mozilla's // methods @@ -1225,10 +1303,15 @@ void decode_url(const gchar* url, gchar* // no need for strn. decoded_url is malloced to sizeof unescaped_url, which // will always be <= decoded size strcpy(*decoded_url, nsCString(unescaped_url).get()); -} - -void get_proxy_info(const char* siteAddr, char** proxy_scheme, char** proxy_host, char** proxy_port, GError *error) -{ +#else + +#endif +} + +NPError +get_proxy_info(const char* siteAddr, char** proxy, uint32_t* len) +{ +#if MOZILLA_VERSION_COLLAPSED < 1090200 nsresult rv; // Initialize service variables @@ -1236,16 +1319,14 @@ void get_proxy_info(const char* siteAddr if (!proxy_svc) { printf("Cannot initialize proxy service\n"); - error->code = 1; - return; + return NPERR_GENERIC_ERROR; } nsCOMPtr io_svc = do_GetService("@mozilla.org/network/io-service;1", &rv); if (NS_FAILED(rv) || !io_svc) { printf("Cannot initialize io service\n"); - error->code = 1; - return; + return NPERR_GENERIC_ERROR; } // uri which needs to be accessed @@ -1259,8 +1340,7 @@ void get_proxy_info(const char* siteAddr // if there is no proxy found, return immediately if (!info) { PLUGIN_DEBUG_1ARG("%s does not need a proxy\n", siteAddr); - error->code = 1; - return; + return NPERR_GENERIC_ERROR; } // if proxy info is available, extract it @@ -1277,8 +1357,7 @@ void get_proxy_info(const char* siteAddr if (!dns_svc) { printf("Cannot initialize DNS service\n"); - error->code = 1; - return; + return NPERR_GENERIC_ERROR; } nsCOMPtr record; @@ -1288,12 +1367,31 @@ void get_proxy_info(const char* siteAddr nsDependentCString ipAddr; record->GetNextAddrAsString(ipAddr); - // pack information in return variables - snprintf(*proxy_scheme, sizeof(char)*32, "%s", ptype.get()); - snprintf(*proxy_host, sizeof(char)*64, "%s", ipAddr.get()); - snprintf(*proxy_port, sizeof(char)*8, "%d", pport); - - PLUGIN_DEBUG_4ARG("Proxy info for %s: %s %s %s\n", siteAddr, *proxy_scheme, *proxy_host, *proxy_port); + snprintf(*proxy, sizeof(char)*1024, "%s://%s:%d", ptype.get(), ipAddr.get(), pport); + *len = strlen(*proxy); + + PLUGIN_DEBUG_2ARG("Proxy info for %s: %s\n", siteAddr, *proxy); + +#else + + if (browser_functions.getvalueforurl) + { + + // As in get_cookie_info, we use the first active instance + GHashTableIter iter; + gpointer id, instance; + + g_hash_table_iter_init (&iter, instance_to_id_map); + g_hash_table_iter_next (&iter, &instance, &id); + + browser_functions.getvalueforurl((NPP) instance, NPNURLVProxy, siteAddr, proxy, len); + } else + { + return NPERR_GENERIC_ERROR; + } +#endif + + return NPERR_NO_ERROR; } // plugin_out_pipe_callback is called when the appletviewer crashes or @@ -1319,7 +1417,7 @@ static NPError static NPError plugin_test_appletviewer () { - PLUGIN_DEBUG_0ARG ("plugin_test_appletviewer\n"); + PLUGIN_DEBUG_1ARG ("plugin_test_appletviewer: %s\n", appletviewer_executable); NPError error = NPERR_NO_ERROR; gchar* command_line[3] = { NULL, NULL, NULL }; @@ -1756,9 +1854,7 @@ NP_Initialize (NPNetscapeFuncs* browserT // the number of browser functions that we may use. if (browserTable->size < sizeof (NPNetscapeFuncs)) { - PLUGIN_ERROR ("Invalid browser function table."); - - return NPERR_INVALID_FUNCTABLE_ERROR; + fprintf (stderr, "ERROR: Invalid browser function table. Some functionality may be restricted.\n"); } // Store in a local table the browser functions that we may use. @@ -1804,10 +1900,17 @@ NP_Initialize (NPNetscapeFuncs* browserT browser_functions.hasmethod = browserTable->hasmethod; browser_functions.releasevariantvalue = browserTable->releasevariantvalue; browser_functions.setexception = browserTable->setexception; + browser_functions.pluginthreadasynccall = browserTable->pluginthreadasynccall; +#if MOZILLA_VERSION_COLLAPSED >= 1090200 + browser_functions.getvalueforurl = browserTable->getvalueforurl; + browser_functions.setvalueforurl = browserTable->setvalueforurl; +#endif // Return to the browser the plugin functions that we implement. pluginTable->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; pluginTable->size = sizeof (NPPluginFuncs); + +#if MOZILLA_VERSION_COLLAPSED < 1090200 pluginTable->newp = NewNPP_NewProc (GCJ_New); pluginTable->destroy = NewNPP_DestroyProc (GCJ_Destroy); pluginTable->setwindow = NewNPP_SetWindowProc (GCJ_SetWindow); @@ -1819,6 +1922,19 @@ NP_Initialize (NPNetscapeFuncs* browserT pluginTable->print = NewNPP_PrintProc (GCJ_Print); pluginTable->urlnotify = NewNPP_URLNotifyProc (GCJ_URLNotify); pluginTable->getvalue = NewNPP_GetValueProc (GCJ_GetValue); +#else + pluginTable->newp = NPP_NewProcPtr (GCJ_New); + pluginTable->destroy = NPP_DestroyProcPtr (GCJ_Destroy); + pluginTable->setwindow = NPP_SetWindowProcPtr (GCJ_SetWindow); + pluginTable->newstream = NPP_NewStreamProcPtr (GCJ_NewStream); + pluginTable->destroystream = NPP_DestroyStreamProcPtr (GCJ_DestroyStream); + pluginTable->asfile = NPP_StreamAsFileProcPtr (GCJ_StreamAsFile); + pluginTable->writeready = NPP_WriteReadyProcPtr (GCJ_WriteReady); + pluginTable->write = NPP_WriteProcPtr (GCJ_Write); + pluginTable->print = NPP_PrintProcPtr (GCJ_Print); + pluginTable->urlnotify = NPP_URLNotifyProcPtr (GCJ_URLNotify); + pluginTable->getvalue = NPP_GetValueProcPtr (GCJ_GetValue); +#endif // Make sure the plugin data directory exists, creating it if // necessary. @@ -1848,6 +1964,7 @@ NP_Initialize (NPNetscapeFuncs* browserT // Set appletviewer_executable. Dl_info info; + int filename_size; if (dladdr ((const void*) GCJ_New, &info) == 0) { PLUGIN_ERROR_TWO ("Failed to determine plugin shared object filename", @@ -1855,15 +1972,31 @@ NP_Initialize (NPNetscapeFuncs* browserT np_error = NPERR_GENERIC_ERROR; goto cleanup_data_directory; } - filename = g_strdup (info.dli_fname); + filename = (gchar*) malloc(sizeof(gchar)*1024); + filename_size = readlink(info.dli_fname, filename, 1023); + if (filename_size >= 0) + { + filename[filename_size] = '\0'; + } + + printf("FILENAME=%s\n", filename); + if (!filename) { PLUGIN_ERROR ("Failed to create plugin shared object filename."); np_error = NPERR_OUT_OF_MEMORY_ERROR; goto cleanup_data_directory; } + + if (filename_size <= 0) + { + free(filename); + filename = g_strdup(info.dli_fname); + } + appletviewer_executable = g_strdup_printf ("%s/../../bin/java", dirname (filename)); + PLUGIN_DEBUG_4ARG(".so is located at: %s and the link points to: %s. Executing java from dir %s to run %s\n", info.dli_fname, filename, dirname (filename), appletviewer_executable); if (!appletviewer_executable) { PLUGIN_ERROR ("Failed to create appletviewer executable name."); --- a/plugin/icedteanp/IcedTeaNPPlugin.h Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/IcedTeaNPPlugin.h Wed Aug 26 15:06:47 2009 -0400 @@ -41,8 +41,15 @@ exception statement from your version. * // Netscape plugin API includes. #include +#include + +#if MOZILLA_VERSION_COLLAPSED < 1090200 #include -#include +#else +#include +#include +#include +#endif // GLib includes. #include @@ -112,7 +119,7 @@ void get_instance_from_id(int id, NPP& i void get_instance_from_id(int id, NPP& instance); /* Given an instance id, return its pointer */ -int get_id_from_instance(NPP* instance); +int get_id_from_instance(NPP instance); /* Sends a message to the appletviewer */ void plugin_send_message_to_appletviewer(gchar const* message); --- a/plugin/icedteanp/IcedTeaPluginRequestProcessor.cc Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/IcedTeaPluginRequestProcessor.cc Wed Aug 26 15:06:47 2009 -0400 @@ -206,21 +206,20 @@ PluginRequestProcessor::eval(std::vector CHECK_JAVA_RESULT(java_result); script.append(*(java_result->return_string)); - std::vector internal_request_params = std::vector(); - ResultData rdata = ResultData(); - nsCOMPtr event; - - internal_request_params.push_back(instance); - internal_request_params.push_back(window_ptr); - internal_request_params.push_back(&script); - - rdata.result_ready = false; - event = new IcedTeaRunnableMethod(&_eval, (void*) &internal_request_params, &rdata); - NS_DispatchToMainThread(event, 0); - - while (!rdata.result_ready) usleep(2000); // Wait till result is ready - - NPVariant* result_variant = (NPVariant*) IcedTeaPluginUtilities::stringToJSID(*(rdata.return_string)); + AyncCallThreadData thread_data = AyncCallThreadData(); + thread_data.result_ready = false; + thread_data.parameters = std::vector(); + thread_data.result = std::string(); + + thread_data.parameters.push_back(instance); + thread_data.parameters.push_back(window_ptr); + thread_data.parameters.push_back(&script); + + browser_functions.pluginthreadasynccall(instance, &_eval, &thread_data); + + while (!thread_data.result_ready) usleep(2000); // Wait till result is ready + + NPVariant* result_variant = (NPVariant*) IcedTeaPluginUtilities::stringToJSID(thread_data.result); std::string result_variant_jniid = std::string(); storeVariantInJava(*result_variant, &result_variant_jniid); @@ -438,25 +437,23 @@ PluginRequestProcessor::call(std::vector for (int i=0; i < args.size(); i++) args_array[i] = args[i]; - std::vector internal_request_params = std::vector(); - ResultData rdata = ResultData(); - nsCOMPtr event; - - internal_request_params.push_back(instance); - internal_request_params.push_back(window_ptr); - internal_request_params.push_back(&window_function_name); - internal_request_params.push_back(&arg_count); - internal_request_params.push_back(args_array); - - printf("Packing %p [%p] %p %s@%p %p %p\n", instance, internal_request_params.at(0), window_ptr, window_function_name.c_str(), &window_function_name, &arg_count, args_array); - - rdata.result_ready = false; - event = new IcedTeaRunnableMethod(&_call, (void*) &internal_request_params, &rdata); - NS_DispatchToMainThread(event, 0); - - while (!rdata.result_ready) usleep(2000); // wait till ready - - NPVariant* result_variant = (NPVariant*) IcedTeaPluginUtilities::stringToJSID(*(rdata.return_string)); + AyncCallThreadData thread_data = AyncCallThreadData(); + thread_data.result_ready = false; + thread_data.parameters = std::vector(); + thread_data.result = std::string(); + + thread_data.parameters.push_back(instance); + thread_data.parameters.push_back(window_ptr); + thread_data.parameters.push_back(&window_function_name); + thread_data.parameters.push_back(&arg_count); + thread_data.parameters.push_back(args_array); + + printf("Packing %p [%p] %p %s@%p %p %p\n", instance, thread_data.parameters.at(0), window_ptr, window_function_name.c_str(), &window_function_name, &arg_count, args_array); + browser_functions.pluginthreadasynccall(instance, &_call, &thread_data); + + while (!thread_data.result_ready) usleep(2000); // wait till ready + + NPVariant* result_variant = (NPVariant*) IcedTeaPluginUtilities::stringToJSID(thread_data.result); std::string result_variant_jniid = std::string(); storeVariantInJava(*result_variant, &result_variant_jniid); @@ -467,7 +464,6 @@ PluginRequestProcessor::call(std::vector plugin_to_java_bus->post(response.c_str()); cleanup: - delete rdata.return_string; free(args_array); } @@ -535,12 +531,9 @@ PluginRequestProcessor::setMember(std::v std::string value = std::string(); std::string type = std::string(); std::string* value_variant_ptr_str; - std::string member_ptr_str = std::string(); - std::vector* internal_request_params = new std::vector(); - + + NPP instance; NPObject* member; - nsCOMPtr event; - ResultData* rdata = new ResultData(); JavaRequestProcessor* java_request = new JavaRequestProcessor(); JavaResultData* java_result; @@ -550,6 +543,7 @@ PluginRequestProcessor::setMember(std::v member = reinterpret_cast (IcedTeaPluginUtilities::stringToJSID(message_parts->at(3))); propertyNameID = message_parts->at(4); valueID = message_parts->at(5); + instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(member); java_request = new JavaRequestProcessor(); java_result = java_request->getString(propertyNameID); @@ -558,7 +552,7 @@ PluginRequestProcessor::setMember(std::v if (java_result->error_occurred) { printf("Unable to get member name for setMember. Error occurred: %s\n", java_result->error_msg); - goto cleanup; + //goto cleanup; } // Copy into local variable before disposing the object @@ -575,7 +569,7 @@ PluginRequestProcessor::setMember(std::v if (java_result->error_occurred) { printf("Unable to get class name for setMember. Error occurred: %s\n", java_result->error_msg); - goto cleanup; + //goto cleanup; } // Copy into local variable before disposing the object @@ -589,26 +583,27 @@ PluginRequestProcessor::setMember(std::v if (java_result->error_occurred) { printf("Unable to get value for setMember. Error occurred: %s\n", java_result->error_msg); - goto cleanup; + //goto cleanup; } value.append(*(java_result->return_string)); - IcedTeaPluginUtilities::JSIDToString(member, &member_ptr_str); - internal_request_params->push_back(&member_ptr_str); - internal_request_params->push_back(&property_name); - internal_request_params->push_back(&type); - internal_request_params->push_back(&value); - - rdata->result_ready = false; - event = new IcedTeaRunnableMethod(&_setMember, (void*) internal_request_params, (void*) rdata); - NS_DispatchToMainThread(event, 0); - - while (!rdata->result_ready) usleep(2000); // wait till ready + AyncCallThreadData thread_data = AyncCallThreadData(); + thread_data.result_ready = false; + thread_data.parameters = std::vector(); + thread_data.result = std::string(); + + thread_data.parameters.push_back(instance); + thread_data.parameters.push_back(member); + thread_data.parameters.push_back(&property_name); + thread_data.parameters.push_back(&type); + thread_data.parameters.push_back(&value); + + browser_functions.pluginthreadasynccall(instance, &_setMember, &thread_data); + + while (!thread_data.result_ready) usleep(2000); // wait till ready cleanup: - delete rdata; - delete rdata->return_string; delete message_parts; delete java_request; @@ -664,25 +659,23 @@ PluginRequestProcessor::sendMember(std:: std::vector args; JavaRequestProcessor java_request = JavaRequestProcessor(); JavaResultData* java_result; - ResultData member_data; + NPObject* parent_ptr; + std::string member_id = std::string(); - std::string parent_id = std::string(); std::string jsObjectClassID = std::string(); std::string jsObjectConstructorID = std::string(); std::string response = std::string(); - nsCOMPtr event; - - std::vector internal_request_params = std::vector(); + int method_id; - int instance; + int instance_id; long reference; // debug printout of parent thread data IcedTeaPluginUtilities::printStringVector("PluginRequestProcessor::getMember:", message_parts); // store info in local variables for easy access - instance = atoi(message_parts->at(1).c_str()); - parent_id += message_parts->at(3); + instance_id = atoi(message_parts->at(1).c_str()); + parent_ptr = reinterpret_cast (IcedTeaPluginUtilities::stringToJSID(message_parts->at(3))); member_id += message_parts->at(4); /** Request data from Java **/ @@ -701,18 +694,21 @@ PluginRequestProcessor::sendMember(std:: reference = internal_req_ref_counter++; - internal_request_params.push_back(&parent_id); - internal_request_params.push_back(java_result->return_string); - - member_data = ResultData(); - member_data.result_ready = false; - - event = new IcedTeaRunnableMethod(&_getMember, (void*) &internal_request_params, (void*) &member_data); - NS_DispatchToMainThread(event, 0); - - while (!member_data.result_ready) usleep(2000); // wait till ready - - PLUGIN_DEBUG_1ARG("Member PTR after internal request: %s\n", member_data.return_string->c_str()); + AyncCallThreadData thread_data = AyncCallThreadData(); + thread_data.result_ready = false; + thread_data.parameters = std::vector(); + thread_data.result = std::string(); + + NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(parent_ptr); + thread_data.parameters.push_back(instance); + thread_data.parameters.push_back(parent_ptr); + thread_data.parameters.push_back(java_result->return_string); + + browser_functions.pluginthreadasynccall(instance, &_getMember, &thread_data); + + while (!thread_data.result_ready) usleep(2000); // wait till ready + + PLUGIN_DEBUG_1ARG("Member PTR after internal request: %s\n", thread_data.result.c_str()); internal_req_ref_counter--; @@ -747,8 +743,8 @@ PluginRequestProcessor::sendMember(std:: // We have the method id. Now create a new object. args.clear(); - args.push_back(*(member_data.return_string)); - java_result = java_request.newObject("", + args.push_back(thread_data.result); + java_result = java_request.newObjectWithConstructor("", jsObjectClassID, jsObjectConstructorID, args); @@ -770,7 +766,6 @@ PluginRequestProcessor::sendMember(std:: // Now be a good citizen and help keep the heap free of garbage cleanup: delete message_parts; // message_parts vector that was allocated by the caller - delete member_data.return_string; pthread_mutex_lock(&tc_mutex); thread_count--; @@ -890,7 +885,7 @@ PluginRequestProcessor::storeVariantInJa boolean_args.clear(); boolean_args.push_back(value_str); - java_result = java_request.newObject("", + java_result = java_request.newObjectWithConstructor("", boolean_classid, boolean_constructor_id, boolean_args); @@ -919,7 +914,7 @@ PluginRequestProcessor::storeVariantInJa integer_args.clear(); integer_args.push_back(value_str); - java_result = java_request.newObject("", + java_result = java_request.newObjectWithConstructor("", integer_classid, integer_constructor_id, integer_args); @@ -948,7 +943,7 @@ PluginRequestProcessor::storeVariantInJa double_args.clear(); double_args.push_back(value_str); - java_result = java_request.newObject("", + java_result = java_request.newObjectWithConstructor("", double_classid, double_constructor_id, double_args); @@ -959,7 +954,11 @@ PluginRequestProcessor::storeVariantInJa else if (NPVARIANT_IS_STRING(variant)) { NPString str = NPVARIANT_TO_STRING(variant); +#if MOZILLA_VERSION_COLLAPSED < 1090200 java_result = java_request.newString(str.utf8characters); +#else + java_result = java_request.newString(str.UTF8Characters); +#endif CHECK_JAVA_RESULT(java_result); result->append(*(java_result->return_string)); } else { @@ -993,7 +992,7 @@ PluginRequestProcessor::storeVariantInJa jsobject_args.clear(); jsobject_args.push_back(value_str); - java_result = java_request.newObject("", + java_result = java_request.newObjectWithConstructor("", jsobject_classid, jsobject_constructor_id, jsobject_args); @@ -1010,28 +1009,26 @@ PluginRequestProcessor::storeVariantInJa * Functions delegated to the main thread * ******************************************/ -void* -_setMember(void* data, void* result) +void +_setMember(void* data) { std::string* property_name; std::string* value; std::string* type; std::string response = std::string(); - std::vector* message_parts = (std::vector*) data; NPP instance; NPVariant* value_variant = new NPVariant(); NPObject* member; NPIdentifier property; - IcedTeaPluginUtilities::printStringPtrVector("PluginRequestProcessor::_setMember - ", message_parts); - - member = reinterpret_cast (IcedTeaPluginUtilities::stringToJSID(*(message_parts->at(0)))); - property_name = message_parts->at(1); - type = message_parts->at(2); - value = message_parts->at(3); - - instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(member); + std::vector parameters = ((AyncCallThreadData*) data)->parameters; + instance = (NPP) parameters.at(0); + member = (NPObject*) parameters.at(1); + property_name = (std::string*) parameters.at(2); + type = (std::string*) parameters.at(3); + value = (std::string*) parameters.at(4); + convertToNPVariant(*value, *type, value_variant); PLUGIN_DEBUG_4ARG("Setting %s on instance %p, object %p to value %s\n", property_name->c_str(), instance, member, value_variant); @@ -1043,17 +1040,15 @@ _setMember(void* data, void* result) response.append(" JavaScriptSetMember "); plugin_to_java_bus->post(response.c_str()); + ((AyncCallThreadData*) data)->result_ready = true; + // free memory delete value_variant; - - ((ResultData*) result)->result_ready = true; - -} - -void* -_getMember(void* data, void* result) -{ - std::string* parent_ptr_str; +} + +void +_getMember(void* data) +{ std::string* member_name; NPObject* parent_ptr; @@ -1062,21 +1057,14 @@ _getMember(void* data, void* result) NPP instance; NPIdentifier member_identifier; - std::vector* message_parts = (std::vector*) data; - - IcedTeaPluginUtilities::printStringPtrVector("PluginRequestProcessor::_getMember - ", message_parts); - - parent_ptr_str = message_parts->at(0); - member_name = message_parts->at(1); + std::vector parameters = ((AyncCallThreadData*) data)->parameters; + + instance = (NPP) parameters.at(0); + parent_ptr = (NPObject*) parameters.at(1); + member_name = (std::string*) parameters.at(2); // Get the corresponding windowId member_identifier = browser_functions.getstringidentifier(member_name->c_str()); - - // Get the window pointer - parent_ptr = reinterpret_cast (IcedTeaPluginUtilities::stringToJSID(parent_ptr_str->c_str())); - - // Get the associated instance - instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(parent_ptr); // Get the NPVariant corresponding to this member PLUGIN_DEBUG_4ARG("Looking for %p %p %p (%s)\n", instance, parent_ptr, member_identifier,member_name->c_str()); @@ -1091,9 +1079,8 @@ _getMember(void* data, void* result) IcedTeaPluginUtilities::JSIDToString(NPVARIANT_TO_OBJECT(member_ptr), &member_ptr_str); PLUGIN_DEBUG_2ARG("Got variant %p (integer value = %s)\n", NPVARIANT_TO_OBJECT(member_ptr), member_ptr_str.c_str()); - ((ResultData*) result)->return_string = new std::string(); - ((ResultData*) result)->return_string->append(member_ptr_str); - ((ResultData*) result)->result_ready = true; + ((AyncCallThreadData*) data)->result.append(member_ptr_str); + ((AyncCallThreadData*) data)->result_ready = true; // store member -> instance link IcedTeaPluginUtilities::storeInstanceID(NPVARIANT_TO_OBJECT(member_ptr), instance); @@ -1101,8 +1088,8 @@ _getMember(void* data, void* result) PLUGIN_DEBUG_0ARG("_getMember returning.\n"); } -void* -_eval(void* data, void* result) +void +_eval(void* data) { NPP instance; NPObject* window_ptr; @@ -1120,24 +1107,31 @@ _eval(void* data, void* result) window_ptr = (NPObject*) call_data->at(1); script_str = (std::string*) call_data->at(2); +#if MOZILLA_VERSION_COLLAPSED < 1090200 script.utf8characters = script_str->c_str(); script.utf8length = script_str->size(); PLUGIN_DEBUG_1ARG("Evaluating: %s\n", script.utf8characters); +#else + script.UTF8Characters = script_str->c_str(); + script.UTF8Length = script_str->size(); + + PLUGIN_DEBUG_1ARG("Evaluating: %s\n", script.UTF8Characters); +#endif + browser_functions.evaluate(instance, window_ptr, &script, eval_result); IcedTeaPluginUtilities::printNPVariant(*eval_result); IcedTeaPluginUtilities::JSIDToString(eval_result, &eval_result_ptr_str); - ((ResultData*) result)->return_string = new std::string(); - ((ResultData*) result)->return_string->append(eval_result_ptr_str); - ((ResultData*) result)->result_ready = true; + ((AyncCallThreadData*) data)->result.append(eval_result_ptr_str); + ((AyncCallThreadData*) data)->result_ready = true; PLUGIN_DEBUG_0ARG("_eval returning\n"); } -void* -_call(void* data, void* result) +void +_call(void* data) { NPP instance; NPObject* window_ptr; @@ -1155,6 +1149,7 @@ _call(void* data, void* result) instance = (NPP) call_data->at(0); window_ptr = (NPObject*) call_data->at(1); function_name = (std::string*) call_data->at(2); + function = browser_functions.getstringidentifier(function_name->c_str()); arg_count = (int*) call_data->at(3); args = (NPVariant*) call_data->at(4); @@ -1164,9 +1159,8 @@ _call(void* data, void* result) browser_functions.invoke(instance, window_ptr, function, args, *arg_count, call_result); IcedTeaPluginUtilities::JSIDToString(&call_result, &call_result_ptr_str); - ((ResultData*) result)->return_string = new std::string(); - ((ResultData*) result)->return_string->append(call_result_ptr_str); - ((ResultData*) result)->result_ready = true; + ((AyncCallThreadData*) data)->result.append(call_result_ptr_str); + ((AyncCallThreadData*) data)->result_ready = true; PLUGIN_DEBUG_0ARG("_call returning\n"); } --- a/plugin/icedteanp/IcedTeaPluginRequestProcessor.h Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/IcedTeaPluginRequestProcessor.h Wed Aug 26 15:06:47 2009 -0400 @@ -46,7 +46,13 @@ exception statement from your version. * #include #include + +#if MOZILLA_VERSION_COLLAPSED < 1090200 #include +#else +#include +#include +#endif #include "IcedTeaRunnable.h" #include "IcedTeaPluginUtils.h" @@ -56,11 +62,12 @@ exception statement from your version. * * Data structure passed to functions called in a new thread. */ -typedef struct struct_thread_data +typedef struct aync_call_thread_data { - std::vector* message_parts; - std::string* source; -} ThreadData; + std::vector parameters; + std::string result; + bool result_ready; +} AyncCallThreadData; /* Internal request reference counter */ static long internal_req_ref_counter; @@ -79,10 +86,10 @@ static void convertToNPVariant(std::stri static void convertToNPVariant(std::string value, std::string type, NPVariant* result_variant); // Internal methods that need to run in main thread -void* _getMember(void* message_parts, void* result); -void* _setMember(void* message_parts, void* result); -void* _call(void* data, void* result); -void* _eval(void* data, void* result); +void _getMember(void* data); +void _setMember(void* data); +void _call(void* data); +void _eval(void* data); static pthread_mutex_t tc_mutex = PTHREAD_MUTEX_INITIALIZER; static int thread_count = 0; --- a/plugin/icedteanp/IcedTeaPluginUtils.cc Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/IcedTeaPluginUtils.cc Wed Aug 26 15:06:47 2009 -0400 @@ -418,13 +418,22 @@ IcedTeaPluginUtilities::printStringVecto delete str; } -gchar* +const gchar* IcedTeaPluginUtilities::getSourceFromInstance(NPP instance) { - GCJPluginData* data = (GCJPluginData*) instance->pdata; - return data->source; -} - + // At the moment, src cannot be securely fetched via NPAPI + // See: + // http://www.mail-archive.com/chromium-dev@googlegroups.com/msg04872.html + + // Since we use the insecure window.location.href attribute to compute + // source, we cannot use it to make security decisions. Therefore, + // instance associated source will always return empty + + //GCJPluginData* data = (GCJPluginData*) instance->pdata; + //return (data->source) ? data->source : ""; + + return "http://null.null"; +} /** * Stores a window pointer <-> instance mapping @@ -518,7 +527,11 @@ IcedTeaPluginUtilities::printNPVariant(N } else if (NPVARIANT_IS_STRING(variant)) { +#if MOZILLA_VERSION_COLLAPSED < 1090200 PLUGIN_DEBUG_1ARG("STRING: %s\n", NPVARIANT_TO_STRING(variant).utf8characters); +#else + PLUGIN_DEBUG_1ARG("STRING: %s\n", NPVARIANT_TO_STRING(variant).UTF8Characters); +#endif } else { @@ -557,8 +570,13 @@ IcedTeaPluginUtilities::NPVariantToStrin else if (NPVARIANT_IS_STRING(variant)) { free(str); +#if MOZILLA_VERSION_COLLAPSED < 1090200 str = (char*) malloc(sizeof(char)*NPVARIANT_TO_STRING(variant).utf8length); sprintf(str, "%s", NPVARIANT_TO_STRING(variant).utf8characters); +#else + str = (char*) malloc(sizeof(char)*NPVARIANT_TO_STRING(variant).UTF8Length); + sprintf(str, "%s", NPVARIANT_TO_STRING(variant).UTF8Characters); +#endif } else { --- a/plugin/icedteanp/IcedTeaPluginUtils.h Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/IcedTeaPluginUtils.h Wed Aug 26 15:06:47 2009 -0400 @@ -56,7 +56,13 @@ exception statement from your version. * #include #include + +#if MOZILLA_VERSION_COLLAPSED < 1090200 #include +#else +#include +#include +#endif #include "IcedTeaNPPlugin.h" @@ -201,7 +207,7 @@ class IcedTeaPluginUtilities static std::string* NPVariantToString(NPVariant variant); - static gchar* getSourceFromInstance(NPP instance); + static const gchar* getSourceFromInstance(NPP instance); static void storeInstanceID(void* member_ptr, NPP instance); --- a/plugin/icedteanp/IcedTeaScriptablePluginObject.cc Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/IcedTeaScriptablePluginObject.cc Wed Aug 26 15:06:47 2009 -0400 @@ -471,6 +471,9 @@ IcedTeaScriptableJavaObject::invoke(NPOb if (java_result->error_occurred) { + // error message must be allocated on heap + char* error_msg = (char*) malloc(java_result->error_msg->length()*sizeof(char)); + browser_functions.setexception(npobj, error_msg); return false; } @@ -541,7 +544,6 @@ IcedTeaScriptableJavaObject::invoke(NPOb PLUGIN_DEBUG_1ARG("Method call returned a string %s\n", return_str); STRINGZ_TO_NPVARIANT(return_str, *result); - printf("%p -- %p\n", return_str, result->value.stringValue.utf8characters); // delete string from java side, as it is no longer needed java_request.deleteReference(return_obj_instance_id); @@ -663,6 +665,49 @@ IcedTeaScriptableJavaObject::construct(N IcedTeaScriptableJavaObject::construct(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result) { - printf ("** Unimplemented: IcedTeaScriptableJavaObject::construct %p\n", npobj); - return false; -} + NPUTF8* method_name = ""; + + // Extract arg type array + PLUGIN_DEBUG_1ARG("IcedTeaScriptableJavaObject::construct %s. Args follow.\n", ((IcedTeaScriptableJavaObject*) npobj)->getClassID().c_str()); + for (int i=0; i < argCount; i++) + { + IcedTeaPluginUtilities::printNPVariant(args[i]); + } + + JavaResultData* java_result; + JavaRequestProcessor java_request = JavaRequestProcessor(); + + NPObject* obj; + std::string class_id = ((IcedTeaScriptableJavaObject*) npobj)->getClassID(); + NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj); + + java_result = java_request.newObject( + IcedTeaPluginUtilities::getSourceFromInstance(instance), + class_id, + args, + argCount); + + if (java_result->error_occurred) + { + // error message must be allocated on heap + int length = java_result->error_msg->length(); + char* error_msg = (char*) malloc((length+1)*sizeof(char)); + strcpy(error_msg, java_result->error_msg->c_str()); + + browser_functions.setexception(npobj, error_msg); + return false; + } + + std::string return_obj_instance_id = std::string(); + std::string return_obj_class_id = class_id; + return_obj_instance_id.append(*(java_result->return_string)); + + obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object( + IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj), + return_obj_class_id, return_obj_instance_id); + + OBJECT_TO_NPVARIANT(obj, *result); + + PLUGIN_DEBUG_0ARG("IcedTeaScriptableJavaObject::construct returning.\n"); + return true; +} --- a/plugin/icedteanp/IcedTeaScriptablePluginObject.h Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/IcedTeaScriptablePluginObject.h Wed Aug 26 15:06:47 2009 -0400 @@ -39,7 +39,12 @@ exception statement from your version. * #ifndef __ICEDTEASCRIPTABLEPLUGINOBJECT_H_ #define __ICEDTEASCRIPTABLEPLUGINOBJECT_H_ +#if MOZILLA_VERSION_COLLAPSED < 1090200 #include "npupp.h" +#else +#include +#include +#endif #include "IcedTeaJavaRequestProcessor.h" #include "IcedTeaNPPlugin.h" --- a/plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java Wed Aug 26 15:06:47 2009 -0400 @@ -37,6 +37,7 @@ exception statement from your version. * package sun.applet; +import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.ArrayList; @@ -152,6 +153,7 @@ public class MethodOverloadResolver { System.out.println("No match found.\n"); } + } /* @@ -217,6 +219,66 @@ public class MethodOverloadResolver { lowestCost = methodCost; } + } + + return ret; + } + + public static Object[] getMatchingConstructor(Object[] callList) { + Object[] ret = null; + Class c = (Class) callList[0]; + + Constructor[] matchingConstructors = getMatchingConstructors(c, callList.length - 1); + + if (debugging) + System.out.println("getMatchingConstructor called with: " + printList(callList)); + + int lowestCost = Integer.MAX_VALUE; + + ArrayList paramList = new ArrayList(); + + for (Constructor matchingConstructor : matchingConstructors) { + + int constructorCost = 0; + Class[] paramTypes = matchingConstructor.getParameterTypes(); + Object[] constructorAndArgs = new Object[paramTypes.length + 1]; + constructorAndArgs[0] = matchingConstructor; + + // Figure out which of the matched methods best represents what we + // want + for (int i = 0; i < paramTypes.length; i++) { + Class paramTypeClass = paramTypes[i]; + Object suppliedParam = callList[i + 1]; + Class suppliedParamClass = suppliedParam != null ? suppliedParam + .getClass() + : null; + + Object[] costAndCastedObj = getCostAndCastedObject( + suppliedParam, paramTypeClass); + constructorCost += (Integer) costAndCastedObj[0]; + Object castedObj = paramTypeClass.isPrimitive() ? costAndCastedObj[1] + : paramTypeClass.cast(costAndCastedObj[1]); + constructorAndArgs[i + 1] = castedObj; + + Class castedObjClass = castedObj == null ? null : castedObj + .getClass(); + Boolean castedObjIsPrim = castedObj == null ? null : castedObj + .getClass().isPrimitive(); + + if (debugging) + System.out.println("Param " + i + " of constructor " + + matchingConstructor + " has cost " + + (Integer) costAndCastedObj[0] + + " original param type " + suppliedParamClass + + " casted to " + castedObjClass + " isPrimitive=" + + castedObjIsPrim + " value " + castedObj); + } + + if ((constructorCost > 0 && constructorCost < lowestCost) || + paramTypes.length == 0) { + ret = constructorAndArgs; + lowestCost = constructorCost; + } } return ret; @@ -300,6 +362,18 @@ public class MethodOverloadResolver { return matchingMethods.toArray(new Method[0]); } + + private static Constructor[] getMatchingConstructors(Class c, int paramCount) { + Constructor[] allConstructors = c.getConstructors(); + ArrayList matchingConstructors = new ArrayList(5); + + for (Constructor cs: allConstructors) { + if (cs.getParameterTypes().length == paramCount) + matchingConstructors.add(cs); + } + + return matchingConstructors.toArray(new Constructor[0]); + } private static Class getPrimitive(Object o) { @@ -415,20 +489,52 @@ public class MethodOverloadResolver { class FooClass { - // First type full match, second Class -> Primitive - public void foo(Boolean b, int i) { - - } - - // Full match - public void foo(Boolean b, Integer i) { - - } - - // First type full match, second Class -> Primitive ambiguity - public void foo(Boolean b, short s) { - - } + public FooClass() {} + + public FooClass(Boolean b, int i) {} + + public FooClass(Boolean b, Integer i) {} + + public FooClass(Boolean b, short s) {} + + public FooClass(String s, int i) {} + + public FooClass(String s, Integer i) {} + + public FooClass(java.lang.Number num) {} + + public FooClass(java.lang.Integer integer) {} + + public FooClass(long l) {} + + public FooClass(double d) {} + + public FooClass(float f) {} + + public FooClass(JSObject j) {} + + public FooClass(BarClass1 b) {} + + public FooClass(BarClass2 b) {} + + public FooClass(String s) {} + + public FooClass(byte b) {} + + public FooClass(String s, Float f) {} + + public FooClass (int i) {} + + public void FooClass() {} + + public void FooClass(boolean b) {} + + + public void foo(Boolean b, int i) {} + + public void foo(Boolean b, Integer i) {} + + public void foo(Boolean b, short s) {} public void foo_string_int(String s, int i) {} --- a/plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java Wed Aug 26 15:06:47 2009 -0400 @@ -202,7 +202,7 @@ class Signature { return c; } - + public static Class primitiveNameToType(String name) { if (name.equals("void")) return Void.TYPE; @@ -912,32 +912,93 @@ public class PluginAppletSecurityContext store.reference(newArray); write(reference, "NewObjectArray " + store.getIdentifier(newArray)); - } else if (message.startsWith("NewObject")) { + } 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 () { + 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); - 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); + 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 () { public Object run() { try { - return m.newInstance(fArguments); + return cons.newInstance(fArguments); } catch (Throwable t) { return t; } @@ -1084,10 +1145,13 @@ public class PluginAppletSecurityContext PluginDebug.debug("target = " + target + " jsSrc=" + jsSrc + " classSrc=" + classSrcURL); + // NPRuntime does not allow cross-site calling. The code below is kept + // in case that changes in the future.. + // if src is not a file and class loader does not map to the same base, UniversalBrowserRead (BrowserReadPermission) must be set - if (!jsSrc.equals("file://") && !jsSrc.equals("[System]") && !classSrcURL.equals(jsSrcURL)) { - acc.checkPermission(new BrowserReadPermission()); - } + //if (!jsSrc.equals("file://") && !jsSrc.equals("[System]") && !classSrcURL.equals(jsSrcURL)) { + // acc.checkPermission(new BrowserReadPermission()); + //} } private void write(int reference, String message) { --- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java Wed Aug 26 15:06:47 2009 -0400 @@ -581,7 +581,6 @@ import com.sun.jndi.toolkit.url.UrlUtil; // Wait for the panel to initialize // (happens in a separate thread) - System.err.println("PANEL = " + panel); while (panel == null || ((o = panel.getApplet()) == null && ((NetxPanel) panel).isAlive())) { try { Thread.sleep(2000); @@ -869,6 +868,8 @@ import com.sun.jndi.toolkit.url.UrlUtil; public void showStatus(String status) { try { // FIXME: change to postCallRequest + // For statuses, we cannot have a newline + status = status.replace("\n", " "); write("status " + status); } catch (IOException exception) { // Deliberately ignore IOException. showStatus may be --- a/plugin/icedteanp/java/sun/applet/PluginCookieInfoRequest.java Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/java/sun/applet/PluginCookieInfoRequest.java Wed Aug 26 15:06:47 2009 -0400 @@ -37,12 +37,6 @@ exception statement from your version. * package sun.applet; -import java.net.HttpCookie; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -import com.sun.jndi.toolkit.url.UrlUtil; /** * This class represents a request object for cookie information for a given URI @@ -50,7 +44,7 @@ import com.sun.jndi.toolkit.url.UrlUtil; public class PluginCookieInfoRequest extends PluginCallRequest { - List cookieObjects = new ArrayList(); + String cookieString = new String(); public PluginCookieInfoRequest(String message, String returnString) { super(message, returnString); @@ -63,50 +57,11 @@ public class PluginCookieInfoRequest ext PluginDebug.debug ("PluginCookieInfoRequest GOT: " + cookieInfo); - String encodedURI = cookieInfo.split(" ")[2]; - // Skip the first 3 components. We are guaranteed 3 components, // so no index -1 to worry about cookieInfo = cookieInfo.substring(cookieInfo.indexOf(' ')+1); cookieInfo = cookieInfo.substring(cookieInfo.indexOf(' ')+1); - cookieInfo = cookieInfo.substring(cookieInfo.indexOf(' ')+1); - - URI siteURI; - try - { - siteURI = new URI(UrlUtil.decode(encodedURI, "UTF-8")); - } catch (Exception e) - { - e.printStackTrace(); - return; - } - - if (cookieInfo != null && cookieInfo.length() > 0) - { - String[] cookies = cookieInfo.split(";"); - - for (int i = 0; i < cookies.length; i++) - { - ArrayList l = new ArrayList(); - - String cookie = cookies[i]; - cookie = cookie.trim(); - String cookieName; - String cookieValue; - - if (cookie.indexOf("=") > 0) { - cookieName = cookie.substring(0, cookie.indexOf("=")); - cookieValue = cookie.substring(cookie.indexOf("=")+1); - - HttpCookie httpCookieObj = new HttpCookie(cookieName, cookieValue); - httpCookieObj.setPath(siteURI.getPath()); - httpCookieObj.setVersion(0); // force v0 - - PluginDebug.debug("Adding cookie info COOKIEN=" + cookieName + " and COOKIEV=" + cookieValue); - cookieObjects.add(httpCookieObj); - } - } - } + cookieString = cookieInfo.substring(cookieInfo.indexOf(' ')+1); setDone(true); } @@ -121,7 +76,7 @@ public class PluginCookieInfoRequest ext return message.startsWith(returnString); } - public List getObject() { - return this.cookieObjects; + public String getObject() { + return this.cookieString; } } --- a/plugin/icedteanp/java/sun/applet/PluginMain.java Wed Aug 26 01:14:21 2009 -0400 +++ b/plugin/icedteanp/java/sun/applet/PluginMain.java Wed Aug 26 15:06:47 2009 -0400 @@ -215,12 +215,12 @@ public class PluginMain System.err.println("Unable to set SSLSocketfactory (may _prevent_ access to sites that should be trusted)! Continuing anyway..."); e.printStackTrace(); } - + // plug in a custom authenticator and proxy selector Authenticator.setDefault(new CustomAuthenticator()); ProxySelector.setDefault(new PluginProxySelector()); - CookieManager ckManager = new CookieManager(new PluginCookieStore(), null); + CookieManager ckManager = new PluginCookieManager(); CookieHandler.setDefault(ckManager); } --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugin/icedteanp/java/sun/applet/PluginCookieManager.java Wed Aug 26 15:06:47 2009 -0400 @@ -0,0 +1,88 @@ +/* PluginCookieManager -- Cookie manager for the plugin + Copyright (C) 2009 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.IOException; +import java.net.CookieManager; +import java.net.HttpCookie; +import java.net.URI; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class PluginCookieManager extends CookieManager +{ + public Map> get(URI uri, + Map> requestHeaders) throws IOException { + // pre-condition check + if (uri == null || requestHeaders == null) { + throw new IllegalArgumentException("Argument is null"); + } + + Map> cookieMap = new java.util.HashMap>(); + + String cookies = (String) PluginAppletViewer + .requestPluginCookieInfo(uri); + List cookieHeader = new java.util.ArrayList(); + + if (cookies != null && cookies.length() > 0) + cookieHeader.add(cookies); + + // Add anything else that mozilla didn't add + for (HttpCookie cookie : getCookieStore().get(uri)) { + // apply path-matches rule (RFC 2965 sec. 3.3.4) + if (pathMatches(uri.getPath(), cookie.getPath())) { + cookieHeader.add(cookie.toString()); + } + } + + cookieMap.put("Cookie", cookieHeader); + return Collections.unmodifiableMap(cookieMap); + } + + private boolean pathMatches(String path, String pathToMatchWith) { + if (path == pathToMatchWith) + return true; + if (path == null || pathToMatchWith == null) + return false; + if (path.startsWith(pathToMatchWith)) + return true; + + return false; + } +} --- a/plugin/icedteanp/java/sun/applet/PluginCookieStore.java Wed Aug 26 01:14:21 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* PluginCookieStore -- Storage for cookie information - Copyright (C) 2009 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.net.HttpCookie; -import java.net.URI; -import java.util.List; - -import sun.net.www.protocol.http.InMemoryCookieStore; - -public class PluginCookieStore extends InMemoryCookieStore -{ - public List get(URI uri) - { - List cookies; - - // Try to fetch it from the plugin, but if something goes - // wrong, fall back. Don't crash! - try - { - cookies = (List) PluginAppletViewer.requestPluginCookieInfo(uri); - - // If cookies is null, something went wrong. Fall back. - if (cookies == null) throw new NullPointerException("Null cookie"); - - } catch (Exception e) - { - PluginDebug.debug("Unable to fetch cookie information from plugin. " + - "Falling back to default."); - e.printStackTrace(); - cookies = super.get(uri); - } - - PluginDebug.debug("Returning cookies " + cookies + " for site: " + uri); - - return cookies; - } -}