Mercurial > hg > icedtea8
changeset 1997:c1c108662db8
This commit:
- Reworks memory allocation to make it less leaky by using heap as little as
possible.
- Implements JSObject.call and JSObject.eval which allow invocation of
JavaScript methods, and execution of arbitrary scripts. Everything except
for array types is currently handled.
- Fixes a few new race conditions that surfaced as result of less
messages/faster initialization.
- Starts laying out call security.
- Fixes unicode handling so that UTF-8 is used correctly across the board.
Most prominently, new sites that now work include:
- Facebook photo uploader
- Yahoo! games applets
- A whole bunch of banking applets
line wrap: on
line diff
--- a/ChangeLog Thu Aug 06 10:43:31 2009 -0400 +++ b/ChangeLog Fri Aug 14 15:58:23 2009 -0400 @@ -1,3 +1,114 @@ +2009-08-14 Deepak Bhole <dbhole@redhat.com> + + * plugin/icedteanp/IcedTeaJavaRequestProcessor.cc + (newMessageOnBus): Handle additional request types. + (postAndWaitForResponse): Modify parameter type and reset the result + before proceeding. + (getToStringValue): Remove all heap allocations and allocate on stack. + (getString): Same. + (deleteReference): Same. + (addReference): Same. + (findClass): Same. + (getClassName): Same. + (getClassID): Same. + (getFieldID): Same. + (getStaticFieldID): Same. + (getField): Same. Also, send the source to Java side. + (getStaticField): Same. + (getMethodID): Remove all heap allocations and allocate on stack. + (getStaticMethodID): Same. + (callStaticMethod): Same. Also, send the source to Java side. + (callMethod): Same. + (call): Same. + (getObjectClass): Remove all heap allocations and allocate on stack. + (newObject): Same. Also, send the source to Java side. + (newString): Remove all heap allocations and allocate on stack. + (hasPackage): Same. + (hasMethod): Same. + (hasField): Same. + (isInstanceOf): New method. + (getAppletObjectInstance): Remove all heap allocations and allocate on + stack. + * plugin/icedteanp/IcedTeaJavaRequestProcessor.h: Bump timeout to 120 to + allow for slower connections. Other misc. changes related to the .cc file + changes. + * plugin/icedteanp/IcedTeaNPPlugin.cc: Moved GCJPluginData decleration to + the header file. Don't initialize message bus and request processors + statically. + (GCJ_New): Initialize the buses and processors. Store source url in plugin + data struct. + (GCJ_Destroy): Cleanup source url pointer. + * plugin/icedteanp/IcedTeaNPPlugin.h: Moved GCJPluginData struct + decleration to here. + * plugin/icedteanp/IcedTeaPluginRequestProcessor.cc + (getInstanceFromMemberPtr): Moved to plugin utils. + (storeInstanceID): Same. + (newMessageOnBus): Handle additional request types. + (dispatch): Remove unused method. + (sendWindow): Remove unnecessary heap allocations and use function stack + instead. + (eval): New function. Evaluates calls to JavaScript functions and returns + the result. Arrays are not yet handled. + (call): New function. Evaluates the given script and returns the result. + Arrays are not yet handled. + (sendString): Remove unnecessary heap allocations and use function stack + instead. + (setMember): Same. + (convertToNPVariant): New function. Narrows given java type to an + NPVariant as per type conversion specifications. + (sendMember): Remove unnecessary heap allocations and use function stack + instead. + (storeVariantInJava): New function. Given an NPVariant, does the + appropriate conversion and saves it on the Java side. Arrays are not yet + handled. + (_eval): New function. Evaluates the script via NPN_Evaluate. Meant to be + run in the main thread. + (_call): New function. Invokes the function via NPN_Invoke. Meant to be run + in the main thread. + * plugin/icedteanp/IcedTeaPluginRequestProcessor.h: Appropriate changes as + necessitated by the above changes in the .cc. + * plugin/icedteanp/IcedTeaPluginUtils.cc + (constructMessagePrefix): All versions of this functions changed to remove + heap allocation, and instead store result in a given pre-allocated parameter. + (getReference): Use an ever growing reference number, and cycle when + integer max approaches. + (releaseReference): Remove code so nothing is done for now. + (itoa): Store result in pre-allocated parameter, rather than on heap. + (getSourceFromInstance): Given an NPP instance, returns the assocated + source. + (storeInstanceID): Moved from IcedTeaPluginRequestProcessor. Associates an + NPObject with an instance. + (getInstanceFromMemberPtr): Moved from IcedTeaPluginRequestProcessor. + Given an NPObject, returns the associated instance. + (variantToClassName): Remove unused method. + * plugin/icedteanp/IcedTeaPluginUtils.h: Appropriate changes as necessitated + by the above changes in the .cc. + * plugin/icedteanp/IcedTeaRunnable.cc (IcedTeaRunnableMethod): Change + result parameter type to void* so that caller/callee can use variable + formats. + * plugin/icedteanp/IcedTeaRunnable.h: Appropriate changes as necessitated + by the above changes in the .cc. + * plugin/icedteanp/IcedTeaScriptablePluginObject.cc: Call storeInstanceID + and getInstanceFromMemberPtr from plugin utils. + (IcedTeaScriptableJavaObject::getProperty): Get the source url and send it to + Java side when making the request. + (IcedTeaScriptableJavaObject::invoke): Same. + * plugin/icedteanp/java/netscape/javascript/JSObject.java: Merge + constructor access control fixes from older plugin. + * plugin/icedteanp/java/sun/applet/GetMemberPluginCallRequest.java: Handle + void and null return types. + * plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java: Add an + additional test case for Boolean. + (getPrimitive): Handle java.lang.Boolean (minor bug fix). + * plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java: Use + URLs when comparing source locations for security verification, rather + than String which return false negatives. + * plugin/icedteanp/java/sun/applet/PluginAppletViewer.java + (handleMessage): Set status to ACTIVE only after initialization finishes. + (AppletEventListener::appletStateChanged): Same. + * plugin/icedteanp/java/sun/applet/PluginCookieInfoRequest.java + (parseReturn): Handle improper cookies from firefox. + 2009-08-06 Deepak Bhole <dbhole@redhat.com> * plugin/icedteanp/IcedTeaJavaRequestProcessor.cc: Handle error messages
--- a/plugin/icedteanp/IcedTeaJavaRequestProcessor.cc Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/IcedTeaJavaRequestProcessor.cc Fri Aug 14 15:58:23 2009 -0400 @@ -111,7 +111,8 @@ (message_parts->at(4) == "GetFieldID") || (message_parts->at(4) == "GetField") || (message_parts->at(4) == "GetStaticField") || - (message_parts->at(4) == "GetJavaObject")) + (message_parts->at(4) == "GetJavaObject") || + (message_parts->at(4) == "IsInstanceOf")) { result->return_identifier = atoi(message_parts->at(5).c_str()); result->return_string->append(message_parts->at(5)); // store it as a string as well, for easy access @@ -159,6 +160,8 @@ JavaRequestProcessor::JavaRequestProcessor() { + PLUGIN_DEBUG_0ARG("JavaRequestProcessor constructor\n"); + // caller frees this result = new JavaResultData(); result->error_msg = new std::string(); @@ -212,15 +215,17 @@ } void -JavaRequestProcessor::postAndWaitForResponse(std::string* message) +JavaRequestProcessor::postAndWaitForResponse(std::string message) { struct timespec t; clock_gettime(CLOCK_REALTIME, &t); t.tv_sec += REQUESTTIMEOUT; // 1 minute timeout - result_ready = false; + // Clear the result + resetResult(); + java_to_plugin_bus->subscribe(this); - plugin_to_java_bus->post(message->c_str()); + plugin_to_java_bus->post(message.c_str()); // Wait for result to be filled in. struct timespec curr_t; @@ -247,7 +252,7 @@ result->error_msg->append("Error: Timed out when waiting for response"); // Report error - PLUGIN_DEBUG_1ARG("Error: Timed out when waiting for response to %s\n", message->c_str()); + PLUGIN_DEBUG_1ARG("Error: Timed out when waiting for response to %s\n", message.c_str()); } java_to_plugin_bus->unSubscribe(this); @@ -263,20 +268,19 @@ JavaResultData* JavaRequestProcessor::getToStringValue(std::string object_id) { - std::string* message; + std::string message = std::string(); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); - message->append(" GetToStringValue "); // get it in UTF8 - message->append(object_id); + message.append(" GetToStringValue "); // get it in UTF8 + message.append(object_id); postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); - delete message; return result; } @@ -291,20 +295,19 @@ JavaResultData* JavaRequestProcessor::getString(std::string string_id) { - std::string* message; + std::string message = std::string(); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); - message->append(" GetStringUTFChars "); // get it in UTF8 - message->append(string_id); + message.append(" GetStringUTFChars "); // get it in UTF8 + message.append(string_id); postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); - delete message; return result; } @@ -318,20 +321,19 @@ void JavaRequestProcessor::deleteReference(std::string object_id) { - std::string* message; + std::string message = std::string(); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); - message->append(" DeleteLocalRef "); - message->append(object_id); + message.append(" DeleteLocalRef "); + message.append(object_id); postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); - delete message; } /** @@ -343,80 +345,73 @@ void JavaRequestProcessor::addReference(std::string object_id) { - std::string* message; + std::string message = std::string(); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); - message->append(" NewGlobalRef "); - message->append(object_id); + message.append(" NewGlobalRef "); + message.append(object_id); postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); - delete message; } JavaResultData* JavaRequestProcessor::findClass(std::string name) { - std::string* message; + std::string message = std::string(); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); - message->append(" FindClass "); - message->append(name); + message.append(" FindClass "); + message.append(name); postAndWaitForResponse(message); - delete message; - return result; } JavaResultData* JavaRequestProcessor::getClassName(std::string objectID) { - std::string* message; + std::string message = std::string(); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); - message->append(" GetClassName "); - message->append(objectID); + message.append(" GetClassName "); + message.append(objectID); postAndWaitForResponse(message); - delete message; - return result; } JavaResultData* JavaRequestProcessor::getClassID(std::string objectID) { - std::string* message; + std::string message = std::string(); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); - message->append(" GetClassID "); - message->append(objectID); + message.append(" GetClassID "); + message.append(objectID); postAndWaitForResponse(message); - delete message; - return result; } @@ -425,25 +420,24 @@ { JavaResultData* java_result; JavaRequestProcessor* java_request = new JavaRequestProcessor(); - std::string* message; + std::string message = std::string(); java_result = java_request->newString(fieldName); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); - message->append(" GetFieldID "); - message->append(classID); - message->append(" "); - message->append(java_result->return_string->c_str()); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); + message.append(" GetFieldID "); + message.append(classID); + message.append(" "); + message.append(java_result->return_string->c_str()); postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); delete java_request; - delete message; return result; } @@ -453,81 +447,81 @@ { JavaResultData* java_result; JavaRequestProcessor* java_request = new JavaRequestProcessor(); - std::string* message; + std::string message = std::string(); java_result = java_request->newString(fieldName); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); - message->append(" GetStaticFieldID "); - message->append(classID); - message->append(" "); - message->append(java_result->return_string->c_str()); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); + message.append(" GetStaticFieldID "); + message.append(classID); + message.append(" "); + message.append(java_result->return_string->c_str()); postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); delete java_request; - delete message; return result; } JavaResultData* -JavaRequestProcessor::getField(std::string classID, std::string fieldName) +JavaRequestProcessor::getField(std::string source, + std::string classID, + std::string fieldName) { JavaResultData* java_result; JavaRequestProcessor* java_request = new JavaRequestProcessor(); - std::string* message; + std::string message = std::string(); java_result = java_request->getFieldID(classID, fieldName); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); - message->append(" GetField "); - message->append(classID); - message->append(" "); - message->append(java_result->return_string->c_str()); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, source, &message); + message.append(" GetField "); + message.append(classID); + message.append(" "); + message.append(java_result->return_string->c_str()); postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); delete java_request; - delete message; return result; } JavaResultData* -JavaRequestProcessor::getStaticField(std::string classID, std::string fieldName) +JavaRequestProcessor::getStaticField(std::string classID, std::string source, + std::string fieldName) { JavaResultData* java_result; JavaRequestProcessor* java_request = new JavaRequestProcessor(); - std::string* message; + std::string message = std::string(); java_result = java_request->getStaticFieldID(classID, fieldName); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); - message->append(" GetStaticField "); - message->append(classID); - message->append(" "); - message->append(java_result->return_string->c_str()); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, source, &message); + message.append(" GetStaticField "); + message.append(classID); + message.append(" "); + message.append(java_result->return_string->c_str()); postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); delete java_request; - delete message; return result; } @@ -537,7 +531,7 @@ std::vector<std::string> args) { JavaRequestProcessor* java_request; - std::string* message; + std::string message = std::string(); std::string* signature; signature = new std::string(); @@ -554,19 +548,18 @@ this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); - *message += " GetMethodID "; - *message += classID; - *message += " "; - *message += browser_functions.utf8fromidentifier(methodName); - *message += " "; - *message += *signature; + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); + message += " GetMethodID "; + message += classID; + message += " "; + message += browser_functions.utf8fromidentifier(methodName); + message += " "; + message += *signature; postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); delete signature; - delete message; return result; } @@ -576,7 +569,7 @@ std::vector<std::string> args) { JavaRequestProcessor* java_request; - std::string* message; + std::string message = std::string(); std::string* signature; signature = new std::string(); @@ -593,19 +586,18 @@ this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); - *message += " GetStaticMethodID "; - *message += classID; - *message += " "; - *message += browser_functions.utf8fromidentifier(methodName); - *message += " "; - *message += *signature; + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); + message += " GetStaticMethodID "; + message += classID; + message += " "; + message += browser_functions.utf8fromidentifier(methodName); + message += " "; + message += *signature; postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); delete signature; - delete message; return result; } @@ -697,7 +689,8 @@ jsObjectConstructorID.append(*(java_result->return_string)); java_request.resetResult(); - // We have class id and constructor ID. So we know we can create the object.. now create the string + // We have class id and constructor ID. So we know we can create the + // object.. now create the string that will be provided as the arg java_result = java_request.newString(stringArg); if (java_result->error_occurred) { @@ -705,6 +698,19 @@ return 0; } + // Create the object + args.clear(); + std::string arg = std::string(); + arg.append(*(java_result->return_string)); + args.push_back(arg); + java_result = java_request.newObject("[System]", jsObjectClassID, jsObjectConstructorID, args); + + if (java_result->error_occurred) { + printf("Unable to create requested object\n"); + return 0; + } + + return java_result->return_identifier; } @@ -719,39 +725,43 @@ } JavaResultData* -JavaRequestProcessor::callStaticMethod(std::string classID, std::string methodName, - const NPVariant* args, int numArgs) +JavaRequestProcessor::callStaticMethod(std::string source, std::string classID, + std::string methodName, + const NPVariant* args, + int numArgs) { - return call(true, classID, methodName, args, numArgs); + return call(source, true, classID, methodName, args, numArgs); } JavaResultData* -JavaRequestProcessor::callMethod(std::string objectID, std::string methodName, - const NPVariant* args, int numArgs) +JavaRequestProcessor::callMethod(std::string source, + std::string objectID, std::string methodName, + const NPVariant* args, int numArgs) { - return call(false, objectID, methodName, args, numArgs); + return call(source, false, objectID, methodName, args, numArgs); } JavaResultData* -JavaRequestProcessor::call(bool isStatic, std::string objectID, +JavaRequestProcessor::call(std::string source, + bool isStatic, std::string objectID, std::string methodName, const NPVariant* args, int numArgs) { - std::string* message; + std::string message = std::string(); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, source, &message); if (isStatic) - *message += " CallStaticMethod "; + message += " CallStaticMethod "; else - *message += " CallMethod "; + message += " CallMethod "; - *message += objectID; - *message += " "; - *message += methodName; - *message += " "; + message += objectID; + message += " "; + message += methodName; + message += " "; // First, we need to load the arguments into the java-side table for (int i=0; i < numArgs; i++) { @@ -760,21 +770,19 @@ { result->error_occurred = true; result->error_msg->append("Unable to create arguments"); - delete message; return result; } char* id = (char*) malloc(sizeof(char)*32); sprintf(id, "%d", objectID); - *message += id; - *message += " "; + message += id; + message += " "; free(id); } postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); - delete message; return result; } @@ -783,50 +791,49 @@ JavaRequestProcessor::getObjectClass(std::string objectID) { JavaRequestProcessor* java_request; - std::string* message; + std::string message = std::string(); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); - *message += " GetObjectClass "; - *message += objectID; + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); + message += " GetObjectClass "; + message += objectID; postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); - delete message; return result; } JavaResultData* -JavaRequestProcessor::newObject(std::string objectID, std::string methodID, - std::vector<std::string> args) +JavaRequestProcessor::newObject(std::string source, std::string objectID, + std::string methodID, + std::vector<std::string> args) { JavaRequestProcessor* java_request; - std::string* message; + std::string message = std::string(); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); - *message += " NewObject "; - *message += objectID; - *message += " "; - *message += methodID; - *message += " "; + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, source, &message); + message += " NewObject "; + message += objectID; + message += " "; + message += methodID; + message += " "; for (int i=0; i < args.size(); i++) { - *message += args[i]; - *message += " "; + message += args[i]; + message += " "; } postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); - delete message; return result; } @@ -835,21 +842,20 @@ JavaRequestProcessor::newString(std::string str) { std::string utf_string = std::string(); - std::string* message; + std::string message = std::string(); IcedTeaPluginUtilities::convertStringToUTF8(&str, &utf_string); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); - message->append(" NewStringUTF "); - message->append(utf_string); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); + message.append(" NewStringUTF "); + message.append(utf_string); postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); - delete message; return result; } @@ -859,23 +865,22 @@ { JavaResultData* java_result; JavaRequestProcessor* java_request = new JavaRequestProcessor(); - std::string* message; + std::string message = std::string(); java_result = java_request->newString(package_name); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); - message->append(" HasPackage "); - message->append(java_result->return_string->c_str()); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); + message.append(" HasPackage "); + message.append(java_result->return_string->c_str()); postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); delete java_request; - delete message; return result; } @@ -885,25 +890,24 @@ { JavaResultData* java_result; JavaRequestProcessor* java_request = new JavaRequestProcessor(); - std::string* message; + std::string message = std::string(); java_result = java_request->newString(method_name); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); - message->append(" HasMethod "); - message->append(classID); - message->append(" "); - message->append(java_result->return_string->c_str()); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); + message.append(" HasMethod "); + message.append(classID); + message.append(" "); + message.append(java_result->return_string->c_str()); postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); delete java_request; - delete message; return result; } @@ -912,26 +916,44 @@ JavaRequestProcessor::hasField(std::string classID, std::string method_name) { JavaResultData* java_result; - JavaRequestProcessor* java_request = new JavaRequestProcessor(); - std::string* message; + JavaRequestProcessor java_request = JavaRequestProcessor(); + std::string message = std::string(); - java_result = java_request->newString(method_name); + java_result = java_request.newString(method_name); this->instance = 0; // context is always 0 (needed for java-side backwards compat.) this->reference = IcedTeaPluginUtilities::getReference(); - message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference); - message->append(" HasField "); - message->append(classID); - message->append(" "); - message->append(java_result->return_string->c_str()); + IcedTeaPluginUtilities::constructMessagePrefix(0, reference, &message); + message.append(" HasField "); + message.append(classID); + message.append(" "); + message.append(java_result->return_string->c_str()); postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference(); - delete java_request; - delete message; + return result; +} + +JavaResultData* +JavaRequestProcessor::isInstanceOf(std::string objectID, std::string classID) +{ + 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, &message); + message.append(" IsInstanceOf "); + message.append(objectID); + message.append(" "); + message.append(classID); + + postAndWaitForResponse(message); + + IcedTeaPluginUtilities::releaseReference(); return result; } @@ -940,10 +962,11 @@ JavaRequestProcessor::getAppletObjectInstance(std::string instanceID) { std::string message = std::string(); - char* ref_str; + std::string ref_str = std::string(); + this->instance = 0; this->reference = IcedTeaPluginUtilities::getReference(); - ref_str = IcedTeaPluginUtilities::itoa(reference); + IcedTeaPluginUtilities::itoa(reference, &ref_str); message = "instance "; message += instanceID; @@ -951,7 +974,7 @@ message += ref_str; message += " GetJavaObject"; - postAndWaitForResponse(&message); + postAndWaitForResponse(message); IcedTeaPluginUtilities::releaseReference();
--- a/plugin/icedteanp/IcedTeaJavaRequestProcessor.h Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/IcedTeaJavaRequestProcessor.h Fri Aug 14 15:58:23 2009 -0400 @@ -47,7 +47,7 @@ #include "IcedTeaPluginUtils.h" #include "IcedTeaScriptablePluginObject.h" -#define REQUESTTIMEOUT 20 +#define REQUESTTIMEOUT 120 /* * This struct holds data specific to a Java operation requested by the plugin @@ -102,24 +102,24 @@ JavaResultData* result; /* Post message on bus and wait */ - void postAndWaitForResponse(std::string* message); + void postAndWaitForResponse(std::string message); /* Creates a argument on java-side with appropriate type */ int createJavaObjectFromVariant(NPVariant variant); // Call a method, static or otherwise, depending on supplied arg - JavaResultData* call(bool isStatic, std::string objectID, - std::string methodName, const NPVariant* args, - int numArgs); + JavaResultData* call(std::string source, bool isStatic, + std::string objectID, std::string methodName, + const NPVariant* args, int numArgs); + + /* Resets the results */ + void resetResult(); public: JavaRequestProcessor(); ~JavaRequestProcessor(); virtual bool newMessageOnBus(const char* message); - /* Resets the results */ - void resetResult(); - /* Increments reference count by 1 */ void addReference(std::string object_id); @@ -132,15 +132,15 @@ /* Returns the string, given the identifier */ JavaResultData* getString(std::string string_id); - /* Returns the method ID from Java side */ - JavaResultData* getMethodID1(NPObject* obj, NPIdentifier methodName, - std::vector<NPVariant> args); - /* Returns the field object */ - JavaResultData* getField(std::string classID, std::string fieldName); + JavaResultData* getField(std::string source, + std::string classID, + std::string fieldName); /* Returns the static field object */ - JavaResultData* getStaticField(std::string classID, std::string fieldName); + JavaResultData* getStaticField(std::string source, + std::string classID, + std::string fieldName); /* Returns the field id */ JavaResultData* getFieldID(std::string classID, std::string fieldName); @@ -157,19 +157,24 @@ std::vector<std::string> args); /* Calls a static method */ - JavaResultData* callStaticMethod(std::string classID, std::string methodName, + JavaResultData* callStaticMethod(std::string source, + std::string classID, + std::string methodName, const NPVariant* args, int numArgs); /* Calls a method on an instance */ - JavaResultData* callMethod(std::string objectID, std::string methodName, + JavaResultData* callMethod(std::string source, + std::string objectID, + std::string methodName, const NPVariant* args, int numArgs); /* Returns the class of the given object */ JavaResultData* getObjectClass(std::string objectID); /* Creates a new object */ - JavaResultData* newObject(std::string objectID, std::string methodID, - std::vector<std::string> args); + JavaResultData* newObject(std::string source, + std::string objectID, std::string methodID, + std::vector<std::string> args); /* Returns the class ID */ JavaResultData* findClass(std::string name); @@ -192,6 +197,9 @@ /* Check if field exists */ JavaResultData* hasField(std::string classID, std::string method_name); + /* Check if given object is instance of given class */ + JavaResultData* isInstanceOf(std::string objectID, std::string classID); + /* Returns the instance ID of the java applet */ JavaResultData* getAppletObjectInstance(std::string instanceID); };
--- a/plugin/icedteanp/IcedTeaNPPlugin.cc Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/IcedTeaNPPlugin.cc Fri Aug 14 15:58:23 2009 -0400 @@ -170,41 +170,18 @@ NPNetscapeFuncs browser_functions; // Various message buses carrying information to/from Java, and internally -MessageBus* plugin_to_java_bus = new MessageBus(); -MessageBus* java_to_plugin_bus = new MessageBus(); +MessageBus* plugin_to_java_bus; +MessageBus* java_to_plugin_bus; //MessageBus* internal_bus = new MessageBus(); // Processor for plugin requests -PluginRequestProcessor* plugin_req_proc = new PluginRequestProcessor(); +PluginRequestProcessor* plugin_req_proc; // Sends messages to Java over the bus -JavaMessageSender* java_req_proc = new JavaMessageSender(); +JavaMessageSender* java_req_proc; GQuark ITNP_PLUGIN_ERROR = g_quark_from_string("IcedTeaNPPlugin"); -// GCJPluginData stores all the data associated with a single plugin -// instance. A separate plugin instance is created for each <APPLET> -// tag. For now, each plugin instance spawns its own applet viewer -// process but this may need to change if we find pages containing -// multiple applets that expect to be running in the same VM. -struct GCJPluginData -{ - // A unique identifier for this plugin window. - gchar* instance_string; - // Mutex to protect appletviewer_alive. - GMutex* appletviewer_mutex; - // Back-pointer to the plugin instance to which this data belongs. - // This should not be freed but instead simply set to NULL. - NPP owner; - // The address of the plugin window. This should not be freed but - // instead simply set to NULL. - gpointer window_handle; - // The last plugin window width sent to us by the browser. - guint32 window_width; - // The last plugin window height sent to us by the browser. - guint32 window_height; -}; - // Documentbase retrieval type-punning union. typedef union { @@ -375,6 +352,10 @@ // Set back-pointer to owner instance. data->owner = instance; + // source of this instance + // don't use documentbase, it is cleared later + data->source = plugin_get_documentbase(instance); + instance->pdata = data; goto cleanup_done; @@ -1715,6 +1696,9 @@ g_free (tofree->instance_string); tofree->instance_string = NULL; + g_free(tofree->source); + tofree->source = NULL; + // cleanup_data: // Eliminate back-pointer to plugin instance. tofree->owner = NULL; @@ -1907,10 +1891,14 @@ PLUGIN_DEBUG_0ARG ("NP_Initialize return\n"); + plugin_req_proc = new PluginRequestProcessor(); + java_req_proc = new JavaMessageSender(); + + java_to_plugin_bus = new MessageBus(); + plugin_to_java_bus = new MessageBus(); + java_to_plugin_bus->subscribe(plugin_req_proc); plugin_to_java_bus->subscribe(java_req_proc); - //internal_bus->subscribe(java_req_proc); - //internal_bus->subscribe(plugin_req_proc); pthread_create (&plugin_request_processor_thread1, NULL, &queue_processor, (void*) plugin_req_proc); pthread_create (&plugin_request_processor_thread2, NULL, &queue_processor, (void*) plugin_req_proc); @@ -2114,7 +2102,6 @@ instance_id.append(*(java_result->return_string)); - java_request.resetResult(); java_result = java_request.getClassID(instance_id); if (java_result->error_occurred)
--- a/plugin/icedteanp/IcedTeaNPPlugin.h Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/IcedTeaNPPlugin.h Fri Aug 14 15:58:23 2009 -0400 @@ -54,6 +54,31 @@ #include "IcedTeaPluginUtils.h" #include "IcedTeaPluginRequestProcessor.h" +// GCJPluginData stores all the data associated with a single plugin +// instance. A separate plugin instance is created for each <APPLET> +// tag. For now, each plugin instance spawns its own applet viewer +// process but this may need to change if we find pages containing +// multiple applets that expect to be running in the same VM. +struct GCJPluginData +{ + // A unique identifier for this plugin window. + gchar* instance_string; + // Mutex to protect appletviewer_alive. + GMutex* appletviewer_mutex; + // Back-pointer to the plugin instance to which this data belongs. + // This should not be freed but instead simply set to NULL. + NPP owner; + // The address of the plugin window. This should not be freed but + // instead simply set to NULL. + gpointer window_handle; + // The last plugin window width sent to us by the browser. + guint32 window_width; + // The last plugin window height sent to us by the browser. + guint32 window_height; + // The source location for this instance + gchar* source; +}; + // Queue processing threads static pthread_t plugin_request_processor_thread1; static pthread_t plugin_request_processor_thread2;
--- a/plugin/icedteanp/IcedTeaPluginRequestProcessor.cc Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/IcedTeaPluginRequestProcessor.cc Fri Aug 14 15:58:23 2009 -0400 @@ -36,6 +36,8 @@ obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ +#include <typeinfo> + #include "IcedTeaNPPlugin.h" #include "IcedTeaPluginRequestProcessor.h" @@ -50,45 +52,6 @@ std::vector< std::vector<std::string>* >* message_queue = new std::vector< std::vector<std::string>* >(); /** - * Given the window pointer, returns the instance associated with it - * - * @param member_ptr The pointer key - * @return The associated instance - */ - -NPP -getInstanceFromMemberPtr(void* member_ptr) -{ - - NPP instance = NULL; - PLUGIN_DEBUG_1ARG("getInstanceFromMemberPtr looking for %p\n", member_ptr); - - std::map<void*, NPP>::iterator iterator = instance_map->find(member_ptr); - - if (iterator != instance_map->end()) - { - instance = instance_map->find(member_ptr)->second; - PLUGIN_DEBUG_2ARG("getInstanceFromMemberPtr found %p. Instance = %p\n", member_ptr, instance); - } - - return instance; -} - -/** - * Stores a window pointer <-> instance mapping - * - * @param member_ptr The pointer key - * @param instance The instance to associate with this pointer - */ - -void -storeInstanceID(void* member_ptr, NPP instance) -{ - PLUGIN_DEBUG_2ARG("Storing instance %p with key %p\n", instance, member_ptr); - instance_map->insert(std::make_pair(member_ptr, instance)); -} - -/** * PluginRequestProcessor constructor. * * Initializes various complex data structures used by the class. @@ -97,7 +60,6 @@ PluginRequestProcessor::PluginRequestProcessor() { this->pendingRequests = new std::map<pthread_t, uintmax_t>(); - instance_map = new std::map<void*, NPP>(); internal_req_ref_counter = 0; } @@ -114,10 +76,6 @@ if (pendingRequests) delete pendingRequests; - - if (instance_map) - delete instance_map; - } /** @@ -156,7 +114,9 @@ return true; } else if (command == "GetMember" || command == "SetMember" || - command == "ToString") + command == "ToString" || + command == "Call" || + command == "Eval") { // Update queue synchronously @@ -179,44 +139,6 @@ } /** - * Delegates further processing to a new thread. - * - * @param func_ptr Pointer to the function to delegate this request to - * @param message_parts The full message, as a vector of strings - * @param src The source URL of the request (may be NULL) - * - * The functions called by dispatch() are started in a new thread, and provided - * a "ThreadData" struct. Since timings are not guaranteed, the struct is - * allocated on the heap and it is upto the called functions to free the - * associated memory when it is safe to do so. - */ - -void PluginRequestProcessor::dispatch(void* func_ptr (void*), std::vector<std::string>* message_parts, std::string* src) -{ - pthread_t thread; - int tries = 0; - ThreadData* tdata = new ThreadData(); - - IcedTeaPluginUtilities::printStringVector("PluginRequestProcessor::dispatch:", message_parts); - - tdata->source = src; - tdata->message_parts = message_parts; - - printf("Threads MAX=%ld, Thread data=%p\n", sysconf(_SC_THREAD_THREADS_MAX), tdata); - while (pthread_create (&thread, NULL, func_ptr, (void*) tdata) == 11 && tries++ < 100) - { - printf("Couldn't create thread. Sleeping and then retrying. TC=%d\n", thread_count); - usleep(1000000); - } - uintmax_t start_time = (uintmax_t) time(NULL); - pthread_mutex_lock(&tc_mutex); - thread_count++; - pthread_mutex_unlock(&tc_mutex); - - PLUGIN_DEBUG_2ARG("pthread %p created. Thread count=%d\n", thread, thread_count); -} - -/** * Sends the window pointer to the Java side. * * @param message_parts The request message. @@ -227,8 +149,8 @@ { std::string type; std::string command; - std::string* response; - std::string* window_ptr_str; + std::string response = std::string(); + std::string window_ptr_str = std::string(); static NPObject* window_ptr; int id; @@ -242,21 +164,311 @@ browser_functions.getvalue(instance, NPNVWindowNPObject, &window_ptr); PLUGIN_DEBUG_3ARG("ID=%d, Instance=%p, WindowPTR = %p\n", id, instance, window_ptr); - window_ptr_str = IcedTeaPluginUtilities::JSIDToString(window_ptr); + IcedTeaPluginUtilities::JSIDToString(window_ptr, &window_ptr_str); // We need the context 0 for backwards compatibility with the Java side - response = IcedTeaPluginUtilities::constructMessagePrefix(0); - *response += " JavaScriptGetWindow "; - *response += *window_ptr_str; + IcedTeaPluginUtilities::constructMessagePrefix(0, &response); + response += " JavaScriptGetWindow "; + response += window_ptr_str; - plugin_to_java_bus->post(response->c_str()); + plugin_to_java_bus->post(response.c_str()); - delete response; - delete window_ptr_str; delete message_parts; // store the instance pointer for future reference - storeInstanceID(window_ptr, instance); + IcedTeaPluginUtilities::storeInstanceID(window_ptr, instance); +} + +/** + * Evaluates the given script + * + * @param message_parts The request message. + */ + +void +PluginRequestProcessor::eval(std::vector<std::string>* message_parts) +{ + JavaRequestProcessor request_processor = JavaRequestProcessor(); + JavaResultData* java_result; + + NPObject* window_ptr; + NPP instance; + std::string script; + NPVariant result; + std::string response = std::string(); + std::string return_type = std::string(); + int id; + + window_ptr = (NPObject*) IcedTeaPluginUtilities::stringToJSID(message_parts->at(3)); + instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(window_ptr); + + java_result = request_processor.getString(message_parts->at(4)); + CHECK_JAVA_RESULT(java_result); + script.append(*(java_result->return_string)); + + std::vector<void*> internal_request_params = std::vector<void*>(); + ResultData rdata = ResultData(); + nsCOMPtr<nsIRunnable> 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)); + std::string result_variant_jniid = std::string(); + storeVariantInJava(*result_variant, &result_variant_jniid); + + IcedTeaPluginUtilities::constructMessagePrefix(0, &response); + response += " JavaScriptEval "; + response += result_variant_jniid; + + plugin_to_java_bus->post(response.c_str()); + + delete message_parts; + +} + +/** + * Calls the given javascript script + * + * @param message_parts The request message. + */ + +void +PluginRequestProcessor::call(std::vector<std::string>* message_parts) +{ + NPP instance; + std::string window_ptr_str; + void* window_ptr; + std::string window_function_name; + std::vector<NPVariant> args = std::vector<NPVariant>(); + std::vector<std::string> arg_ids = std::vector<std::string>(); + int arg_count; + std::string response = std::string(); + JavaRequestProcessor java_request = JavaRequestProcessor(); + JavaResultData* java_result; + + // window + window_ptr_str = message_parts->at(3); + window_ptr = IcedTeaPluginUtilities::stringToJSID(window_ptr_str); + + // instance + instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(window_ptr); + + // function name + java_result = java_request.getString(message_parts->at(4)); + CHECK_JAVA_RESULT(java_result); + window_function_name.append(*(java_result->return_string)); + + // arguments + for (int i=5; i < message_parts->size(); i++) + { + arg_ids.push_back(message_parts->at(i)); + } + + std::string number_class_id = std::string(); + std::string boolean_class_id = std::string(); + std::string byte_class_id = std::string(); + std::string char_class_id = std::string(); + std::string string_class_id = std::string(); + + java_result = java_request.findClass("java.lang.Number"); + CHECK_JAVA_RESULT(java_result); + number_class_id.append(*(java_result->return_string)); + + java_result = java_request.findClass("java.lang.Boolean"); + CHECK_JAVA_RESULT(java_result); + boolean_class_id.append(*(java_result->return_string)); + + java_result = java_request.findClass("java.lang.Byte"); + CHECK_JAVA_RESULT(java_result); + byte_class_id.append(*(java_result->return_string)); + + java_result = java_request.findClass("java.lang.Character"); + CHECK_JAVA_RESULT(java_result); + char_class_id.append(*(java_result->return_string)); + + java_result = java_request.findClass("java.lang.String"); + CHECK_JAVA_RESULT(java_result); + string_class_id.append(*(java_result->return_string)); + + // determine arguments + for (int i=0; i < arg_ids.size(); i++) + { + bool isNum = false; + bool isBool = false; + bool isByte = false; + bool isChar = false; + bool isString = false; + std::string id = arg_ids[i]; + std::string arg_class_name = std::string(); + std::string arg_value = std::string(); + NPVariant* variant = new NPVariant(); + + // instanceOf calls are very fast, so just do them all even + // if one of them is true + + // Number + java_result = java_request.isInstanceOf(id, number_class_id); + CHECK_JAVA_RESULT(java_result); + if (*(java_result->return_string) == "1") + { + isNum = true; + } + + // Boolean + java_result = java_request.isInstanceOf(id, boolean_class_id); + CHECK_JAVA_RESULT(java_result); + if (*(java_result->return_string) == "1") + { + isBool = true; + } + + void storeVariantInJava(NPVariant variant, std::string* result); + // Byte + java_result = java_request.isInstanceOf(id, byte_class_id); + CHECK_JAVA_RESULT(java_result); + if (*(java_result->return_string) == "1") + { + isByte = true; + } + + // Character + java_result = java_request.isInstanceOf(id, char_class_id); + CHECK_JAVA_RESULT(java_result); + if (*(java_result->return_string) == "1") + { + isChar = true; + } + + // String + java_result = java_request.isInstanceOf(id, string_class_id); + CHECK_JAVA_RESULT(java_result); + if (*(java_result->return_string) == "1") + { + isString = true; + } + + if (isNum) + { + int i; + double d; + + java_result = java_request.getString(id); + CHECK_JAVA_RESULT(java_result); + + if (java_result->return_string->find(".")) + { + d = strtod(java_result->return_string->c_str(), NULL); + DOUBLE_TO_NPVARIANT(d, *variant); + } else + { + i = atoi(java_result->return_string->c_str()); + INT32_TO_NPVARIANT(d, *variant); + } + + + } else if (isChar || isByte) + { + int i; + std::string str = std::string(); + + java_result = java_request.getString(id); + CHECK_JAVA_RESULT(java_result); + str.append(*(java_result->return_string)); + + // FIXME: No multi-byte char support yet + i = str[i]; + + INT32_TO_NPVARIANT(i, *variant); + + } else if (isBool) + { + bool b; + + java_result = java_request.getString(id); + CHECK_JAVA_RESULT(java_result); + + if (java_result->return_string->find("true") == 0) + b = true; + else + b = false; + + BOOLEAN_TO_NPVARIANT(b, *variant); + + } else if (isString) + { + java_result = java_request.getString(id); + CHECK_JAVA_RESULT(java_result); + + // string is non-primitive and needs to be allocated on the heap + NPUTF8* arg_str = (NPUTF8*) malloc(sizeof(NPUTF8)*java_result->return_string->size() + 1); + strcpy(arg_str, java_result->return_string->c_str()); + + STRINGZ_TO_NPVARIANT(arg_str, *variant); + } else + { + // Else complex java object + + std::string class_id; // class id of object + + NPObject* obj; + + java_result = java_request.getClassID(id); + CHECK_JAVA_RESULT(java_result); + class_id.append(*(java_result->return_string)); + + obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object(instance, class_id, id); + + OBJECT_TO_NPVARIANT(obj, *variant); + + } + + args.push_back(*variant); + } + + arg_count = args.size(); + NPVariant *args_array = (NPVariant*) malloc(sizeof(NPVariant)*args.size()); + for (int i=0; i < args.size(); i++) + args_array[i] = args[i]; + + std::vector<void*> internal_request_params = std::vector<void*>(); + ResultData rdata = ResultData(); + nsCOMPtr<nsIRunnable> 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)); + std::string result_variant_jniid = std::string(); + storeVariantInJava(*result_variant, &result_variant_jniid); + + IcedTeaPluginUtilities::constructMessagePrefix(0, &response); + response += " JavaScriptCall "; + response += result_variant_jniid; + + plugin_to_java_bus->post(response.c_str()); + + cleanup: + delete rdata.return_string; + free(args_array); } /** @@ -271,9 +483,9 @@ NPVariant* variant; std::string* variant_string; std::string* variant_string_id; - JavaRequestProcessor* java_request; + JavaRequestProcessor java_request = JavaRequestProcessor(); JavaResultData* java_result; - std::string* response; + std::string response = std::string(); int instance; instance = atoi(message_parts->at(1).c_str()); @@ -282,8 +494,7 @@ variant = (NPVariant*) IcedTeaPluginUtilities::stringToJSID(variant_ptr); variant_string = IcedTeaPluginUtilities::NPVariantToString(*variant); - java_request = new JavaRequestProcessor(); - java_result = java_request->newString(*variant_string); + java_result = java_request.newString(*variant_string); if (java_result->error_occurred) { @@ -294,15 +505,13 @@ variant_string_id = java_result->return_string; // We need the context 0 for backwards compatibility with the Java side - response = IcedTeaPluginUtilities::constructMessagePrefix(instance); - *response += " JavaScriptToString "; - *response += *variant_string_id; + IcedTeaPluginUtilities::constructMessagePrefix(instance, &response); + response += " JavaScriptToString "; + response += *variant_string_id; - plugin_to_java_bus->post(response->c_str()); + plugin_to_java_bus->post(response.c_str()); cleanup: - delete java_request; - delete response; delete variant_string; delete message_parts; @@ -322,17 +531,18 @@ { std::string valueID; std::string propertyNameID; - std::string* property_name = new std::string(); - std::string* value = new std::string(); - std::string* type = new std::string(); + std::string property_name = std::string(); + 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<std::string*>* internal_request_params = new std::vector<std::string*>(); NPObject* member; nsCOMPtr<nsIRunnable> event; ResultData* rdata = new ResultData(); - JavaRequestProcessor* java_request; + JavaRequestProcessor* java_request = new JavaRequestProcessor(); JavaResultData* java_result; IcedTeaPluginUtilities::printStringVector("PluginRequestProcessor::_setMember - ", message_parts); @@ -352,7 +562,7 @@ } // Copy into local variable before disposing the object - property_name->append(*(java_result->return_string)); + property_name.append(*(java_result->return_string)); delete java_request; // Based on the value ID, find the type and string value @@ -369,7 +579,7 @@ } // Copy into local variable before disposing the object - type->append(*(java_result->return_string)); + type.append(*(java_result->return_string)); delete java_request; java_request = new JavaRequestProcessor(); @@ -382,18 +592,23 @@ goto cleanup; } - value->append(*(java_result->return_string)); + value.append(*(java_result->return_string)); - internal_request_params->push_back(IcedTeaPluginUtilities::JSIDToString(member)); - internal_request_params->push_back(property_name); - internal_request_params->push_back(type); - internal_request_params->push_back(value); + 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, rdata); + event = new IcedTeaRunnableMethod(&_setMember, (void*) internal_request_params, (void*) rdata); NS_DispatchToMainThread(event, 0); + while (!rdata->result_ready) usleep(2000); // wait till ready + cleanup: + delete rdata; + delete rdata->return_string; delete message_parts; delete java_request; @@ -446,18 +661,18 @@ PluginRequestProcessor::sendMember(std::vector<std::string>* message_parts) { // member initialization - std::vector<std::string>* args; - JavaRequestProcessor* java_request; + std::vector<std::string> args; + JavaRequestProcessor java_request = JavaRequestProcessor(); JavaResultData* java_result; - ResultData* member_data; - std::string* member_id = new std::string(); - std::string* parent_id = new std::string(); - std::string* jsObjectClassID = new std::string(); - std::string* jsObjectConstructorID = new std::string(); - std::string* response = new std::string(); + ResultData member_data; + 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<nsIRunnable> event; - std::vector<std::string*>* internal_request_params = new std::vector<std::string*>(); + std::vector<std::string*> internal_request_params = std::vector<std::string*>(); int method_id; int instance; long reference; @@ -467,14 +682,13 @@ // store info in local variables for easy access instance = atoi(message_parts->at(1).c_str()); - *parent_id += message_parts->at(3); - *member_id += message_parts->at(4); + parent_id += message_parts->at(3); + member_id += message_parts->at(4); /** Request data from Java **/ // make a new request for getString, to get the name of the identifier - java_request = new JavaRequestProcessor(); - java_result = java_request->getString(*member_id); + java_result = java_request.getString(member_id); // the result we want is in result_string (assuming there was no error) if (java_result->error_occurred) @@ -487,27 +701,22 @@ reference = internal_req_ref_counter++; - internal_request_params->push_back(parent_id); - internal_request_params->push_back(java_result->return_string); + internal_request_params.push_back(&parent_id); + internal_request_params.push_back(java_result->return_string); - member_data = new ResultData(); - member_data->result_ready = false; + member_data = ResultData(); + member_data.result_ready = false; - event = new IcedTeaRunnableMethod(&_getMember, (void*) internal_request_params, member_data); + event = new IcedTeaRunnableMethod(&_getMember, (void*) &internal_request_params, (void*) &member_data); NS_DispatchToMainThread(event, 0); - while (!member_data->result_ready) // wait till ready - { - usleep(2000); - } + 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()); + PLUGIN_DEBUG_1ARG("Member PTR after internal request: %s\n", member_data.return_string->c_str()); internal_req_ref_counter--; - delete java_request; - java_request = new JavaRequestProcessor(); - java_result = java_request->findClass("netscape.javascript.JSObject"); + java_result = java_request.findClass("netscape.javascript.JSObject"); // the result we want is in result_string (assuming there was no error) if (java_result->error_occurred) @@ -516,21 +725,15 @@ //goto cleanup; } - *jsObjectClassID += *(java_result->return_string); - - // We have the result. Free the request memory - delete java_request; - - java_request = new JavaRequestProcessor(); + jsObjectClassID.append(*(java_result->return_string)); - args = new std::vector<std::string>(); + args = std::vector<std::string>(); std::string longArg = "J"; - args->push_back(longArg); + args.push_back(longArg); - java_result = java_request->getMethodID( - *(jsObjectClassID), - browser_functions.getstringidentifier("<init>"), - *args); + java_result = java_request.getMethodID(jsObjectClassID, + browser_functions.getstringidentifier("<init>"), + args); // the result we want is in result_string (assuming there was no error) if (java_result->error_occurred) @@ -539,19 +742,16 @@ //goto cleanup; } - *jsObjectConstructorID += *(java_result->return_string); - - delete args; - delete java_request; + jsObjectConstructorID.append(*(java_result->return_string)); // We have the method id. Now create a new object. - java_request = new JavaRequestProcessor(); - args = new std::vector<std::string>(); - args->push_back(*(member_data->return_string)); - java_result = java_request->newObject(*jsObjectClassID, - *jsObjectConstructorID, - *args); + args.clear(); + args.push_back(*(member_data.return_string)); + java_result = java_request.newObject("", + jsObjectClassID, + jsObjectConstructorID, + args); // the result we want is in result_string (assuming there was no error) if (java_result->error_occurred) @@ -561,22 +761,16 @@ } - response = IcedTeaPluginUtilities::constructMessagePrefix(0); - response->append(" JavaScriptGetMember "); - response->append(java_result->return_string->c_str()); - plugin_to_java_bus->post(response->c_str()); + IcedTeaPluginUtilities::constructMessagePrefix(0, &response); + response.append(" JavaScriptGetMember "); + response.append(java_result->return_string->c_str()); + plugin_to_java_bus->post(response.c_str()); // Now be a good citizen and help keep the heap free of garbage cleanup: - delete args; - delete java_request; // request object - delete member_id; // member id string delete message_parts; // message_parts vector that was allocated by the caller - delete internal_request_params; // delete the internal requests params vector - delete jsObjectClassID; // delete object that holds the jsobject - delete member_data->return_string; - delete member_data; + delete member_data.return_string; pthread_mutex_lock(&tc_mutex); thread_count--; @@ -620,6 +814,18 @@ pthread_mutex_lock(&syn_write_mutex); processor->setMember(message_parts); pthread_mutex_unlock(&syn_write_mutex); + } else if (command == "Call") + { + // write methods are synchronized + pthread_mutex_lock(&syn_write_mutex); + processor->call(message_parts); + pthread_mutex_unlock(&syn_write_mutex); + } else if (command == "Eval") + { + // write methods are synchronized + pthread_mutex_lock(&syn_write_mutex); + processor->eval(message_parts); + pthread_mutex_unlock(&syn_write_mutex); } else { // Nothing matched @@ -639,17 +845,178 @@ PLUGIN_DEBUG_0ARG("Queue processing stopped.\n"); } +/* Stores the variant on java side + * + * @param variant The variant to store + * @param result The result + */ +void +PluginRequestProcessor::storeVariantInJava(NPVariant variant, std::string* result) +{ + + // FIXME: Should null and void have some different representation? + // the spec doesn't say.. + JavaRequestProcessor java_request = JavaRequestProcessor(); + JavaResultData* java_result; + + if (NPVARIANT_IS_VOID(variant) || NPVARIANT_IS_NULL(variant)) + { + NPString str = NPVARIANT_TO_STRING(variant); + java_result = java_request.newString(""); + CHECK_JAVA_RESULT(java_result); + result->append(*(java_result->return_string)); + } + else if (NPVARIANT_IS_BOOLEAN(variant)) + { + std::string boolean_classid = std::string(); + std::string boolean_constructor_id = std::string(); + std::vector<std::string> boolean_args = std::vector<std::string>(); + std::string value_str; + if (NPVARIANT_TO_BOOLEAN(variant)) + value_str = "true"; + else + value_str = "false"; + + java_result = java_request.findClass("java.lang.Boolean"); + CHECK_JAVA_RESULT(java_result); + boolean_classid.append(*(java_result->return_string)); + + boolean_args.push_back("Z"); + java_result = java_request.getMethodID(boolean_classid, + browser_functions.getstringidentifier("<init>"), + boolean_args); + CHECK_JAVA_RESULT(java_result); + boolean_constructor_id.append(*(java_result->return_string)); + + boolean_args.clear(); + boolean_args.push_back(value_str); + java_result = java_request.newObject("", + boolean_classid, + boolean_constructor_id, + boolean_args); + + CHECK_JAVA_RESULT(java_result); + result->append(*(java_result->return_string)); + } + else if (NPVARIANT_IS_INT32(variant)) + { + std::string integer_classid = std::string(); + std::string integer_constructor_id = std::string(); + std::vector<std::string> integer_args = std::vector<std::string>(); + std::string value_str = std::string(); + IcedTeaPluginUtilities::itoa(NPVARIANT_TO_INT32(variant), &value_str); + + java_result = java_request.findClass("java.lang.Integer"); + CHECK_JAVA_RESULT(java_result); + integer_classid.append(*(java_result->return_string)); + + integer_args.push_back("I"); + java_result = java_request.getMethodID(integer_classid, + browser_functions.getstringidentifier("<init>"), + integer_args); + CHECK_JAVA_RESULT(java_result); + integer_constructor_id.append(*(java_result->return_string)); + + integer_args.clear(); + integer_args.push_back(value_str); + java_result = java_request.newObject("", + integer_classid, + integer_constructor_id, + integer_args); + + CHECK_JAVA_RESULT(java_result); + result->append(*(java_result->return_string)); + } + else if (NPVARIANT_IS_DOUBLE(variant)) + { + std::string double_classid = std::string(); + std::string double_constructor_id = std::string(); + std::vector<std::string> double_args = std::vector<std::string>(); + std::string value_str = std::string(); + IcedTeaPluginUtilities::itoa(NPVARIANT_TO_DOUBLE(variant), &value_str); + + java_result = java_request.findClass("java.lang.Double"); + CHECK_JAVA_RESULT(java_result); + double_classid.append(*(java_result->return_string)); + + double_args.push_back("J"); + java_result = java_request.getMethodID(double_classid, + browser_functions.getstringidentifier("<init>"), + double_args); + CHECK_JAVA_RESULT(java_result); + double_constructor_id.append(*(java_result->return_string)); + + double_args.clear(); + double_args.push_back(value_str); + java_result = java_request.newObject("", + double_classid, + double_constructor_id, + double_args); + + CHECK_JAVA_RESULT(java_result); + result->append(*(java_result->return_string)); + } + else if (NPVARIANT_IS_STRING(variant)) + { + NPString str = NPVARIANT_TO_STRING(variant); + java_result = java_request.newString(str.utf8characters); + CHECK_JAVA_RESULT(java_result); + result->append(*(java_result->return_string)); + } else { + + + // Else it is a complex object + if (typeid(IcedTeaScriptableJavaObject*) == typeid(NPVARIANT_TO_OBJECT(variant))) + { + IcedTeaScriptableJavaObject* obj; + obj = (IcedTeaScriptableJavaObject*) NPVARIANT_TO_OBJECT(variant); + result->append(obj->getInstanceID()); + } else { + // Else store it as a JSObject + std::string jsobject_classid = std::string(); + std::string jsobject_constructor_id = std::string(); + std::vector<std::string> jsobject_args = std::vector<std::string>(); + std::string value_str = std::string(); + printf("Got NPObject %p\n", NPVARIANT_TO_OBJECT(variant)); + IcedTeaPluginUtilities::JSIDToString(NPVARIANT_TO_OBJECT(variant), &value_str); + + java_result = java_request.findClass("netscape.javascript.JSObject"); + CHECK_JAVA_RESULT(java_result); + jsobject_classid.append(*(java_result->return_string)); + + jsobject_args.push_back("J"); + java_result = java_request.getMethodID(jsobject_classid, + browser_functions.getstringidentifier("<init>"), + jsobject_args); + CHECK_JAVA_RESULT(java_result); + jsobject_constructor_id.append(*(java_result->return_string)); + + jsobject_args.clear(); + jsobject_args.push_back(value_str); + java_result = java_request.newObject("", + jsobject_classid, + jsobject_constructor_id, + jsobject_args); + + CHECK_JAVA_RESULT(java_result); + result->append(*(java_result->return_string)); + } + } + +} + + /****************************************** * Functions delegated to the main thread * ******************************************/ void* -_setMember(void* data, ResultData* result) +_setMember(void* data, void* result) { std::string* property_name; std::string* value; std::string* type; - std::string* response; + std::string response = std::string(); std::vector<std::string*>* message_parts = (std::vector<std::string*>*) data; NPP instance; @@ -664,7 +1031,7 @@ type = message_parts->at(2); value = message_parts->at(3); - instance = getInstanceFromMemberPtr(member); + instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(member); 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); @@ -672,28 +1039,26 @@ property = browser_functions.getstringidentifier(property_name->c_str()); browser_functions.setproperty(instance, member, property, value_variant); - response = IcedTeaPluginUtilities::constructMessagePrefix(0); - response->append(" JavaScriptSetMember "); - plugin_to_java_bus->post(response->c_str()); + IcedTeaPluginUtilities::constructMessagePrefix(0, &response); + response.append(" JavaScriptSetMember "); + plugin_to_java_bus->post(response.c_str()); // free memory - IcedTeaPluginUtilities::freeStringPtrVector(message_parts); delete value_variant; - delete response; - result->result_ready = true; + ((ResultData*) result)->result_ready = true; } void* -_getMember(void* data, ResultData* result) +_getMember(void* data, void* result) { std::string* parent_ptr_str; std::string* member_name; NPObject* parent_ptr; NPVariant member_ptr; - std::string* member_ptr_str; + std::string member_ptr_str = std::string(); NPP instance; NPIdentifier member_identifier; @@ -711,7 +1076,7 @@ parent_ptr = reinterpret_cast <NPObject*> (IcedTeaPluginUtilities::stringToJSID(parent_ptr_str->c_str())); // Get the associated instance - instance = getInstanceFromMemberPtr(parent_ptr); + 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()); @@ -723,16 +1088,85 @@ browser_functions.getproperty(instance, parent_ptr, member_identifier, &member_ptr); IcedTeaPluginUtilities::printNPVariant(member_ptr); - member_ptr_str = IcedTeaPluginUtilities::JSIDToString(NPVARIANT_TO_OBJECT(member_ptr)); - PLUGIN_DEBUG_2ARG("Got variant %p (integer value = %s)\n", NPVARIANT_TO_OBJECT(member_ptr), member_ptr_str->c_str()); + 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()); - result->return_string = member_ptr_str; - result->result_ready = true; + ((ResultData*) result)->return_string = new std::string(); + ((ResultData*) result)->return_string->append(member_ptr_str); + ((ResultData*) result)->result_ready = true; // store member -> instance link - storeInstanceID(NPVARIANT_TO_OBJECT(member_ptr), instance); + IcedTeaPluginUtilities::storeInstanceID(NPVARIANT_TO_OBJECT(member_ptr), instance); PLUGIN_DEBUG_0ARG("_getMember returning.\n"); +} - return result; +void* +_eval(void* data, void* result) +{ + NPP instance; + NPObject* window_ptr; + std::string* script_str; + NPIdentifier script_identifier; + NPString script = NPString(); + NPVariant* eval_result = new NPVariant(); + std::string eval_result_ptr_str = std::string(); + + PLUGIN_DEBUG_0ARG("_eval called\n"); + + std::vector<void*>* call_data = (std::vector<void*>*) data; + + instance = (NPP) call_data->at(0); + window_ptr = (NPObject*) call_data->at(1); + script_str = (std::string*) call_data->at(2); + + script.utf8characters = script_str->c_str(); + script.utf8length = script_str->size(); + + PLUGIN_DEBUG_1ARG("Evaluating: %s\n", script.utf8characters); + 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; + + PLUGIN_DEBUG_0ARG("_eval returning\n"); } + + +void* +_call(void* data, void* result) +{ + NPP instance; + NPObject* window_ptr; + std::string* function_name; + NPIdentifier function; + int* arg_count; + NPVariant* args; + NPVariant* call_result = new NPVariant(); + std::string call_result_ptr_str = std::string(); + + PLUGIN_DEBUG_0ARG("_call called\n"); + + std::vector<void*>* call_data = (std::vector<void*>*) data; + + 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); + + printf("Extracted %p -- %p -- %s@%p -- %d -- %p\n", instance, window_ptr, function_name->c_str(), function_name, *arg_count, args); + + 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; + + PLUGIN_DEBUG_0ARG("_call returning\n"); +}
--- a/plugin/icedteanp/IcedTeaPluginRequestProcessor.h Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/IcedTeaPluginRequestProcessor.h Fri Aug 14 15:58:23 2009 -0400 @@ -62,20 +62,13 @@ std::string* source; } ThreadData; - -/* Map holding window pointer<->instance relationships */ -static std::map<void*, NPP>* instance_map; - /* Internal request reference counter */ static long internal_req_ref_counter; // JS request processor methods -extern NPP getInstanceFromMemberPtr(void* member_ptr); -extern void storeInstanceID(void* member_ptr, NPP instance); static void* requestFromMainThread(); static void* getSlot(void* tdata); static void* setSlot(void* tdata); -static void* eval(void* tdata); static void* removeMember(void* tdata); static void* call(void* tdata); static void* finalize(void* tdata); @@ -86,8 +79,10 @@ 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, ResultData* result); -void* _setMember(void* message_parts, ResultData* result); +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); static pthread_mutex_t tc_mutex = PTHREAD_MUTEX_INITIALIZER; static int thread_count = 0; @@ -119,6 +114,9 @@ /* Send main window pointer to Java */ void sendWindow(std::vector<std::string>* message_parts); + /* Stores the variant on java side */ + void storeVariantInJava(NPVariant variant, std::string* result); + public: PluginRequestProcessor(); /* Constructor */ ~PluginRequestProcessor(); /* Destructor */ @@ -134,6 +132,13 @@ /* Send string value of requested object */ void sendString(std::vector<std::string>* message_parts); + + /* Evaluate the given script */ + void eval(std::vector<std::string>* message_parts); + + /* Evaluate the given script */ + void call(std::vector<std::string>* message_parts); + }; #endif // __ICEDTEAPLUGINREQUESTPROCESSOR_H__
--- a/plugin/icedteanp/IcedTeaPluginUtils.cc Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/IcedTeaPluginUtils.cc Fri Aug 14 15:58:23 2009 -0400 @@ -50,6 +50,7 @@ // Initialize static variables int IcedTeaPluginUtilities::reference = 0; pthread_mutex_t IcedTeaPluginUtilities::reference_mutex = PTHREAD_MUTEX_INITIALIZER; +std::map<void*, NPP>* IcedTeaPluginUtilities::instance_map = new std::map<void*, NPP>(); /** * Given a context number, constructs a message prefix to send to Java @@ -58,19 +59,17 @@ * @return The string prefix (allocated on heap) */ -std::string* -IcedTeaPluginUtilities::constructMessagePrefix(int context) +void +IcedTeaPluginUtilities::constructMessagePrefix(int context, std::string *result) { - std::string* result = new std::string(); - char* context_str = itoa(context); + std::string context_str = std::string(); - *result += "context "; - result->append(context_str); - *result += " reference -1"; + itoa(context, &context_str); - free(context_str); + result->append("context "); + result->append(context_str); + result->append(" reference -1"); - return result; } /** @@ -79,29 +78,24 @@ * * @param context The context of the request * @param rerefence The reference number of the request - * @return The string prefix (allocated on heap) + * @param result The message */ -std::string* -IcedTeaPluginUtilities::constructMessagePrefix(int context, int reference) +void +IcedTeaPluginUtilities::constructMessagePrefix(int context, int reference, std::string* result) { // Until security is implemented, use file:// source for _everything_ - /*std::string* result = new std::string(); - char* context_str = itoa(context); - char* reference_str = itoa(reference); + std::string context_str = std::string(); + std::string reference_str = std::string(); + + itoa(context, &context_str); + itoa(reference, &reference_str); *result += "context "; result->append(context_str); *result += " reference "; result->append(reference_str); - - free(context_str); - free(reference_str); - - return result;*/ - - return IcedTeaPluginUtilities::constructMessagePrefix(context, reference, "file://"); } /** @@ -111,42 +105,43 @@ * @param context The context of the request * @param rerefence The reference number of the request * @param address The address for the script that made the request - * @return The string prefix (allocated on heap) + * @param result The message */ -std::string* +void IcedTeaPluginUtilities::constructMessagePrefix(int context, int reference, - const char* address) + std::string address, + std::string* result) { - std::string* result = new std::string(); - char* context_str = itoa(context); - char* reference_str = itoa(reference); + std::string context_str = std::string(); + std::string reference_str = std::string(); + + itoa(context, &context_str); + itoa(reference, &reference_str); *result += "context "; result->append(context_str); *result += " reference "; result->append(reference_str); - *result += " src "; - result->append(address); - free(context_str); - free(reference_str); - - return result; + if (address.length() > 0) + { + *result += " src "; + result->append(address); + } } /** * Returns a string representation of a void pointer * * @param id The pointer - * @return The string representation (Allocated on heap) + * @param result The string representation */ -std::string* -IcedTeaPluginUtilities::JSIDToString(void* id) +void +IcedTeaPluginUtilities::JSIDToString(void* id, std::string* result) { - std::string* result = new std::string(); char* id_str = (char*) malloc(sizeof(char)*20); // max = long long = 8446744073709551615 == 19 chars if (sizeof(void*) == sizeof(long long)) @@ -158,12 +153,10 @@ sprintf(id_str, "%lu", id); // else use long } - *result += id_str; + result->append(id_str); PLUGIN_DEBUG_2ARG("Converting pointer %p to %s\n", id, id_str); free(id_str); - - return result; } /** @@ -201,6 +194,12 @@ IcedTeaPluginUtilities::getReference() { pthread_mutex_lock(&reference_mutex); + + // If we are nearing the max, reset + if (reference > 0x7FFFFFFF - 10) { + reference = 0; + } + reference++; pthread_mutex_unlock(&reference_mutex); @@ -215,25 +214,24 @@ void IcedTeaPluginUtilities::releaseReference() { - pthread_mutex_lock(&reference_mutex); - reference--; - pthread_mutex_unlock(&reference_mutex); + // do nothing for now } /** * Converts integer to char* * * @param i The integer to convert to ascii - * @return The converted string (allocated on heap) + * @param result The resulting string */ -char* -IcedTeaPluginUtilities::itoa(int i) +void +IcedTeaPluginUtilities::itoa(int i, std::string* result) { // largest possible integer is 10 digits long - char* result = (char*) malloc(sizeof(char)*11); - sprintf(result, "%d", i); + char* int_str = (char*) malloc(sizeof(char)*11); + sprintf(int_str, "%d", i); + result->append(int_str); - return result; + free(int_str); } /** @@ -332,16 +330,17 @@ { std::ostringstream ostream; - char* length = itoa(str->length()); + std::string length = std::string(); + itoa(str->length(), &length); + ostream << length; - free(length); // UTF-8 characters are 4-bytes max + space + '\0' char* hex_value = (char*) malloc(sizeof(char)*10); for (int i = 0; i < str->length(); i++) { - sprintf(hex_value, " %x", (*str)[i]); + sprintf(hex_value, " %hx", str->at(i)); ostream << hex_value; } @@ -419,6 +418,54 @@ delete str; } +gchar* +IcedTeaPluginUtilities::getSourceFromInstance(NPP instance) +{ + GCJPluginData* data = (GCJPluginData*) instance->pdata; + return data->source; +} + + +/** + * Stores a window pointer <-> instance mapping + * + * @param member_ptr The pointer key + * @param instance The instance to associate with this pointer + */ + +void +IcedTeaPluginUtilities::storeInstanceID(void* member_ptr, NPP instance) +{ + PLUGIN_DEBUG_2ARG("Storing instance %p with key %p\n", instance, member_ptr); + instance_map->insert(std::make_pair(member_ptr, instance)); +} + + +/** + * Given the window pointer, returns the instance associated with it + * + * @param member_ptr The pointer key + * @return The associated instance + */ + +NPP +IcedTeaPluginUtilities::getInstanceFromMemberPtr(void* member_ptr) +{ + + NPP instance = NULL; + PLUGIN_DEBUG_1ARG("getInstanceFromMemberPtr looking for %p\n", member_ptr); + + std::map<void*, NPP>::iterator iterator = instance_map->find(member_ptr); + + if (iterator != instance_map->end()) + { + instance = instance_map->find(member_ptr)->second; + PLUGIN_DEBUG_2ARG("getInstanceFromMemberPtr found %p. Instance = %p\n", member_ptr, instance); + } + + return instance; +} + /* * Similar to printStringVector, but takes a vector of string pointers instead * @@ -446,41 +493,6 @@ delete str; } -std::string* -IcedTeaPluginUtilities::variantToClassName(NPVariant variant) -{ - - std::string* java_type = new std::string(); - - if (NPVARIANT_IS_VOID(variant)) - { - *java_type += "V"; - } else if (NPVARIANT_IS_BOOLEAN(variant)) - { - *java_type += "Z"; - } else if (NPVARIANT_IS_INT32(variant)) - { - *java_type += "I"; - } else if (NPVARIANT_IS_DOUBLE(variant)) - { - *java_type += "D"; - } else if (NPVARIANT_IS_STRING(variant)) - { - *java_type += "Ljava/lang/String;"; - } else if (NPVARIANT_IS_OBJECT(variant)) - { - printf("** Unimplemented: IcedTeaPluginUtilities::variantToClassName(variant type=obj)\n"); - } else if (NPVARIANT_IS_NULL(variant)) - { - printf("** Unimplemented: IcedTeaPluginUtilities::variantToClassName(variant type=null)\n"); - } else - { - printf("** Unimplemented: IcedTeaPluginUtilities::variantToClassName(variant type=unknown)\n"); - } - - return java_type; -} - void IcedTeaPluginUtilities::printNPVariant(NPVariant variant) {
--- a/plugin/icedteanp/IcedTeaPluginUtils.h Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/IcedTeaPluginUtils.h Fri Aug 14 15:58:23 2009 -0400 @@ -49,11 +49,17 @@ #include <cstring> #include <iostream> #include <list> +#include <map> #include <queue> #include <sstream> #include <string> #include <vector> +#include <npapi.h> +#include <npupp.h> + +#include "IcedTeaNPPlugin.h" + #define PLUGIN_DEBUG_0ARG(str) \ do \ { \ @@ -104,6 +110,16 @@ } \ } while (0) +#define CHECK_JAVA_RESULT(result_data) \ +{ \ + if (((JavaResultData*) result_data)->error_occurred) \ + { \ + printf("Error: Error occurred on Java side: %s.\n", \ + ((JavaResultData*) result_data)->error_msg->c_str()); \ + return; \ + } \ +} + /* * Misc. utility functions * @@ -119,20 +135,26 @@ /* Mutex lock for updating reference count */ static pthread_mutex_t reference_mutex; + /* Map holding window pointer<->instance relationships */ + static std::map<void*, NPP>* instance_map; + public: /* Constructs message prefix with given context */ - static std::string* constructMessagePrefix(int context); + static void constructMessagePrefix(int context, + std::string* result); /* Constructs message prefix with given context and reference */ - static std::string* constructMessagePrefix(int context, int reference); + static void constructMessagePrefix(int context, int reference, + std::string* result); /* Constructs message prefix with given context, reference and src */ - static std::string* constructMessagePrefix(int context, int reference, - const char* address); + static void constructMessagePrefix(int context, int reference, + std::string address, + std::string* result); /* Converts given pointer to a string representation */ - static std::string* JSIDToString(void* id); + static void JSIDToString(void* id, std::string* result); /* Converts the given string representation to a pointer */ static void* stringToJSID(std::string id_str); @@ -143,8 +165,8 @@ /* Decrements reference count */ static void releaseReference(); - /* Converts the given interget to char* array */ - static char* itoa(int i); + /* Converts the given integer to a string */ + static void itoa(int i, std::string* result); /* Frees the given vector and the strings that its contents point to */ static void freeStringPtrVector(std::vector<std::string*>* v); @@ -178,6 +200,12 @@ static void printNPVariant(NPVariant variant); static std::string* NPVariantToString(NPVariant variant); + + static gchar* getSourceFromInstance(NPP instance); + + static void storeInstanceID(void* member_ptr, NPP instance); + + static NPP getInstanceFromMemberPtr(void* member_ptr); }; /* @@ -244,11 +272,4 @@ void post(const char* message); }; -/* - * JNI map used for mediating between NPVariants and Java objects - * - * - * - */ - #endif // __ICEDTEAPLUGINUTILS_H__
--- a/plugin/icedteanp/IcedTeaRunnable.cc Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/IcedTeaRunnable.cc Fri Aug 14 15:58:23 2009 -0400 @@ -55,7 +55,7 @@ return NS_ERROR_NOT_IMPLEMENTED; } -IcedTeaRunnableMethod::IcedTeaRunnableMethod (Method method, void* thread_data, ResultData* result) +IcedTeaRunnableMethod::IcedTeaRunnableMethod (Method method, void* thread_data, void* result) : method (method), thread_data(thread_data), result(result) @@ -69,6 +69,7 @@ NS_IMETHODIMP IcedTeaRunnableMethod::Run () { + printf("Running method...\n"); (*method) (thread_data, result); return NS_OK; }
--- a/plugin/icedteanp/IcedTeaRunnable.h Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/IcedTeaRunnable.h Fri Aug 14 15:58:23 2009 -0400 @@ -48,7 +48,7 @@ /* * This struct holds the result from the main-thread dispatched method */ -typedef struct java_result +typedef struct result_data { // Return identifier (if applicable) int return_identifier; @@ -85,16 +85,16 @@ { public: - typedef void* (*Method) (void*, ResultData*); + typedef void* (*Method) (void*, void*); - IcedTeaRunnableMethod (Method, void* thread_data, ResultData* result); + IcedTeaRunnableMethod (Method, void* thread_data, void* result); NS_IMETHOD Run (); ~IcedTeaRunnableMethod (); Method method; void* thread_data; - ResultData* result; + void* result; }; #endif /* MOZILLA */
--- a/plugin/icedteanp/IcedTeaScriptablePluginObject.cc Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/IcedTeaScriptablePluginObject.cc Fri Aug 14 15:58:23 2009 -0400 @@ -41,7 +41,7 @@ IcedTeaScriptablePluginObject::IcedTeaScriptablePluginObject(NPP instance) { this->instance = instance; - storeInstanceID(this, instance); + IcedTeaPluginUtilities::storeInstanceID(this, instance); } void @@ -163,7 +163,7 @@ ((IcedTeaScriptableJavaPackageObject*) scriptable_object)->setPackageName(name); - storeInstanceID(scriptable_object, instance); + IcedTeaPluginUtilities::storeInstanceID(scriptable_object, instance); return scriptable_object; } @@ -253,7 +253,6 @@ // No such package. Do we have a class with that name? if (!hasProperty) { - java_request->resetResult(); java_result = java_request->findClass(property_name); } @@ -290,13 +289,15 @@ { PLUGIN_DEBUG_0ARG("Returning package object\n"); obj = IcedTeaScriptablePluginObject::get_scriptable_java_package_object( - getInstanceFromMemberPtr(npobj), + IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj), property_name.c_str()); } else { PLUGIN_DEBUG_0ARG("Returning Java object\n"); - obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object(getInstanceFromMemberPtr(npobj), *(java_result->return_string), "0"); + obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object( + IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj), + *(java_result->return_string), "0"); } OBJECT_TO_NPVARIANT(obj, *result); @@ -368,7 +369,7 @@ if (instance_id != "0") ((IcedTeaScriptableJavaObject*) scriptable_object)->setInstanceIdentifier(instance_id); - storeInstanceID(scriptable_object, instance); + IcedTeaPluginUtilities::storeInstanceID(scriptable_object, instance); return scriptable_object; } @@ -450,16 +451,22 @@ std::string callee; std::string source; + NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj); + if (instance_id.length() == 0) // Static { printf("Calling static method\n"); callee = ((IcedTeaScriptableJavaObject*) npobj)->getClassID(); - java_result = java_request.callStaticMethod(callee, browser_functions.utf8fromidentifier(name), args, argCount); + java_result = java_request.callStaticMethod( + IcedTeaPluginUtilities::getSourceFromInstance(instance), + callee, browser_functions.utf8fromidentifier(name), args, argCount); } else { printf("Calling method normally\n"); callee = ((IcedTeaScriptableJavaObject*) npobj)->getInstanceID(); - java_result = java_request.callMethod(callee, browser_functions.utf8fromidentifier(name), args, argCount); + java_result = java_request.callMethod( + IcedTeaPluginUtilities::getSourceFromInstance(instance), + callee, browser_functions.utf8fromidentifier(name), args, argCount); } if (java_result->error_occurred) @@ -509,7 +516,6 @@ return_obj_instance_id.append(*(java_result->return_string)); // Find out the class name first, because string is a special case - java_request.resetResult(); java_result = java_request.getClassName(return_obj_instance_id); if (java_result->error_occurred) @@ -522,7 +528,6 @@ if (return_obj_class_name == "java.lang.String") { // String is a special case as NPVariant can handle it directly - java_request.resetResult(); java_result = java_request.getString(return_obj_instance_id); if (java_result->error_occurred) @@ -531,7 +536,7 @@ } // needs to be on the heap - NPUTF8* return_str = (NPUTF8*) browser_functions.memalloc(sizeof(NPUTF8)*java_result->return_string->size() + 1); + NPUTF8* return_str = (NPUTF8*) malloc(sizeof(NPUTF8)*java_result->return_string->size() + 1); strcpy(return_str, java_result->return_string->c_str()); PLUGIN_DEBUG_1ARG("Method call returned a string %s\n", return_str); @@ -544,8 +549,6 @@ // Else this is a regular class. Reference the class object so // we can construct an NPObject with it and the instance - - java_request.resetResult(); java_result = java_request.findClass(return_obj_class_name); if (java_result->error_occurred) @@ -556,7 +559,9 @@ return_obj_class_id.append(*(java_result->return_string)); NPObject* obj; - obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object(getInstanceFromMemberPtr(npobj), return_obj_class_id, return_obj_instance_id); + obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object( + IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj), + return_obj_class_id, return_obj_instance_id); OBJECT_TO_NPVARIANT(obj, *result); } @@ -609,12 +614,14 @@ std::string class_id = ((IcedTeaScriptableJavaObject*) npobj)->getClassID(); std::string callee = ((IcedTeaScriptableJavaObject*) npobj)->getClassID(); - java_result = java_request.getField(callee, browser_functions.utf8fromidentifier(name)); + NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj); + java_result = java_request.getField( + IcedTeaPluginUtilities::getSourceFromInstance(instance), + callee, browser_functions.utf8fromidentifier(name)); std::string object_id = *(java_result->return_string); // get the class of this object - java_request.resetResult(); java_result = java_request.getObjectClass(object_id); if (java_result->error_occurred) @@ -622,7 +629,9 @@ return false; } - obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object(getInstanceFromMemberPtr(npobj), *(java_result->return_string), object_id); + obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object( + IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj), + *(java_result->return_string), object_id); OBJECT_TO_NPVARIANT(obj, *result);
--- a/plugin/icedteanp/java/netscape/javascript/JSObject.java Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/java/netscape/javascript/JSObject.java Fri Aug 14 15:58:23 2009 -0400 @@ -47,6 +47,10 @@ package netscape.javascript; import java.applet.Applet; +import java.security.AccessControlContext; +import java.security.AccessControlException; +import java.security.AccessController; +import java.security.BasicPermission; import sun.applet.PluginAppletViewer; import sun.applet.PluginDebug; @@ -102,13 +106,37 @@ /** * it is illegal to construct a JSObject manually */ - // FIXME: make private! public JSObject(int jsobj_addr) { - PluginDebug.debug ("JSObject int CONSTRUCTOR"); - internal = jsobj_addr; + this((long) jsobj_addr); } public JSObject(long jsobj_addr) { + + // See if the caller has permission + + try { + AccessController.getContext().checkPermission(new JSObjectCreatePermission()); + } catch (AccessControlException ace) { + + // If not, only caller with JSObject.getWindow on the stack may + // make this call unprivileged. + + // Although this check is inefficient, it should happen only once + // during applet init, so we look the other way + + StackTraceElement[] stack = Thread.currentThread().getStackTrace(); + boolean mayProceed = false; + + for (int i=0; i < stack.length; i++) { + if (stack[i].getClassName().equals("netscape.javascript.JSObject") && + stack[i].getMethodName().equals("getWindow")) { + mayProceed = true; + } + } + + if (!mayProceed) throw ace; + } + PluginDebug.debug ("JSObject long CONSTRUCTOR"); internal = jsobj_addr; } @@ -234,7 +262,7 @@ internal = ((PluginAppletViewer) applet.getAppletContext()).getWindow(); PluginDebug.debug ("GOT IT: " + internal); - return new JSObject(internal); + return new JSObject((long) internal); } @@ -259,5 +287,4 @@ return false; } - }
--- a/plugin/icedteanp/java/sun/applet/GetMemberPluginCallRequest.java Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/java/sun/applet/GetMemberPluginCallRequest.java Fri Aug 14 15:58:23 2009 -0400 @@ -49,9 +49,10 @@ public void parseReturn(String message) { PluginDebug.debug ("GetMEMBerparseReturn GOT: " + message); String[] args = message.split(" "); - // FIXME: add thread ID to messages to support multiple - // threads using the netscape.javascript package. - object = AppletSecurityContextManager.getSecurityContext(0).getObject(Integer.parseInt(args[1])); + // FIXME: Is it even possible to distinguish between null and void + // here? + if (args[1] != "null" && args[1] != "void") + object = AppletSecurityContextManager.getSecurityContext(0).getObject(Integer.parseInt(args[1])); setDone(true); }
--- a/plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java Fri Aug 14 15:58:23 2009 -0400 @@ -138,6 +138,11 @@ Object[] o14 = { fc.getClass(), "foo_noargs" }; list.add(o14); + // method which takes a primitive bool, given a Boolean + String s15 = "foo_boolonly()"; + Object[] o15 = { fc.getClass(), "foo_boolonly", new Boolean(true) }; + list.add(o15); + for (Object[] o : list) { Object[] methodAndArgs = getMatchingMethod(o); if (debugging) @@ -312,6 +317,8 @@ return java.lang.Float.TYPE; } else if (o instanceof java.lang.Double) { return java.lang.Double.TYPE; + } else if (o instanceof java.lang.Boolean) { + return java.lang.Boolean.TYPE; } return o.getClass(); @@ -408,16 +415,6 @@ class FooClass { - // Normal, null => non primitive type - public void foo(Boolean b) { - - } - - // Class -> primitive - public void foo(boolean b) { - - } - // First type full match, second Class -> Primitive public void foo(Boolean b, int i) { @@ -472,6 +469,8 @@ public void foo_int_only (int i) {} public void foo_noargs() {} + + public void foo_boolonly(boolean b) {} } class BarClass1 {}
--- a/plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java Fri Aug 14 15:58:23 2009 -0400 @@ -60,6 +60,7 @@ import sun.reflect.generics.repository.MethodRepository; import net.sourceforge.jnlp.runtime.JNLPRuntime; +import netscape.javascript.JSObjectCreatePermission; @@ -232,7 +233,7 @@ public class PluginAppletSecurityContext { - public static Hashtable<ClassLoader, String> classLoaders = new Hashtable<ClassLoader, String>(); + public static Hashtable<ClassLoader, URL> classLoaders = new Hashtable<ClassLoader, URL>(); // FIXME: make private public PluginObjectStore store = new PluginObjectStore(); @@ -260,8 +261,16 @@ } JNLPRuntime.disableExit(); + + URL u = null; + try { + u = new URL("file://"); + } catch (Exception e) { + e.printStackTrace(); + } + - this.classLoaders.put(liveconnectLoader, "file://"); + this.classLoaders.put(liveconnectLoader, u); } private static <V> V parseCall(String s, ClassLoader cl, Class<V> c) { @@ -300,7 +309,7 @@ return store.getObject(new Integer(s)); } - public void associateSrc(ClassLoader cl, String src) { + public void associateSrc(ClassLoader cl, URL src) { PluginDebug.debug("Associating " + cl + " with " + src); this.classLoaders.put(cl, src); } @@ -610,7 +619,7 @@ arguments[1] = methodName; for (int i = 0; i < args.length - 3; i++) { arguments[i+2] = store.getObject(parseCall(args[3 + i], null, Integer.class)); - PluginDebug.debug("GOT ARG: " + arguments[i]); + PluginDebug.debug("GOT ARG: " + arguments[i+2]); } Object[] matchingMethodAndArgs = MethodOverloadResolver.getMatchingMethod(arguments); @@ -954,7 +963,7 @@ while (i < length) { c = Integer.parseInt(args[j++], 16); byteArray[i++] = (byte) c; - } + } ret = new String(byteArray, "UTF-8"); PluginDebug.debug("NEWSTRINGUTF: " + ret); @@ -1065,12 +1074,18 @@ if (target.getClassLoader() == null) return; - String classSrc = this.classLoaders.get(target.getClassLoader()); + URL classSrcURL = this.classLoaders.get(target.getClassLoader()); + URL jsSrcURL = null; + try { + jsSrcURL = new URL(jsSrc); + } catch (Exception e) { + e.printStackTrace(); + } - PluginDebug.debug("target = " + target + " jsSrc=" + jsSrc + " classSrc=" + classSrc); + PluginDebug.debug("target = " + target + " jsSrc=" + jsSrc + " classSrc=" + classSrcURL); // 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]") && !classSrc.equals(jsSrc)) { + if (!jsSrc.equals("file://") && !jsSrc.equals("[System]") && !classSrcURL.equals(jsSrcURL)) { acc.checkPermission(new BrowserReadPermission()); } } @@ -1354,12 +1369,15 @@ CodeSource cs = new CodeSource((URL) null, (java.security.cert.Certificate [])null); - if (src != null) { + if (src != null && src.length() > 0) { try { cs = new CodeSource(new URL(src + "/"), (java.security.cert.Certificate[]) null); } catch (MalformedURLException mfue) { // do nothing } + } else { + JSObjectCreatePermission perm = new JSObjectCreatePermission(); + grantedPermissions.add(perm); } ProtectionDomain pd = new ProtectionDomain(cs, grantedPermissions, null, null);
--- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java Fri Aug 14 15:58:23 2009 -0400 @@ -346,7 +346,7 @@ } } - AppletSecurityContextManager.getSecurityContext(0).associateSrc(a.getClass().getClassLoader(), codeBase); + AppletSecurityContextManager.getSecurityContext(0).associateSrc(a.getClass().getClassLoader(), doc); try { write("initialized"); @@ -354,6 +354,16 @@ ioe.printStackTrace(); } + // Panel initialization cannot be aborted mid-way. + // Once it is initialized, double check to see if this + // panel needs to stay around.. + if (status.get(identifier).equals(PAV_INIT_STATUS.INACTIVE)) { + PluginDebug.debug("Inactive flag set. Destroying applet instance " + identifier); + applets.get(identifier).handleMessage(-1, "destroy"); + } else { + status.put(identifier, PAV_INIT_STATUS.ACTIVE); + } + } public static void setStreamhandler(PluginStreamHandler sh) { @@ -415,16 +425,6 @@ new StringReader(request.tag), new URL(request.documentbase)); requests.remove(identifier); - - // Panel initialization cannot be aborted mid-way. - // Once it is initialized, double check to see if this - // panel needs to stay around.. - if (status.get(identifier).equals(PAV_INIT_STATUS.INACTIVE)) { - PluginDebug.debug("Inactive flag set. Destroying applet instance " + identifier); - applets.get(identifier).handleMessage(-1, "destroy"); - } else { - status.put(identifier, PAV_INIT_STATUS.ACTIVE); - } } else { PluginDebug.debug ("REQUEST HANDLE NOT SET: " + request.handle + ". BYPASSING"); @@ -467,16 +467,6 @@ PluginDebug.debug ("REQUEST HANDLE, DONE PARSING " + Thread.currentThread()); - // Panel initialization cannot be aborted mid-way. - // Once it is initialized, double check to see if this - // panel needs to stay around.. - if (status.get(identifier).equals(PAV_INIT_STATUS.INACTIVE)) { - PluginDebug.debug("Inactive flag set. Destroying applet instance " + identifier); - applets.get(identifier).handleMessage(-1, "destroy"); - } else { - status.put(identifier, PAV_INIT_STATUS.ACTIVE); - } - } else { PluginDebug.debug ("REQUEST TAG NOT SET: " + request.tag + ". BYPASSING"); } @@ -526,6 +516,8 @@ } } catch (Exception e) { + e.printStackTrace(); + // If an exception happened during pre-init, we need to update status if (status.get(identifier).equals(PAV_INIT_STATUS.PRE_INIT)) status.put(identifier, PAV_INIT_STATUS.INACTIVE); @@ -589,7 +581,8 @@ // Wait for the panel to initialize // (happens in a separate thread) - while ((o = panel.getApplet()) == null && ((NetxPanel) panel).isAlive()) { + System.err.println("PANEL = " + panel); + while (panel == null || ((o = panel.getApplet()) == null && ((NetxPanel) panel).isAlive())) { try { Thread.sleep(2000); PluginDebug.debug("Waiting for applet to initialize..."); @@ -1075,12 +1068,18 @@ // FIXME: convenience method for this long line. AppletSecurityContextManager.getSecurityContext(0).store(name); int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name); - AppletSecurityContextManager.getSecurityContext(0).store(args); - int argsID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(args); + + String argIDs = ""; + for (Object arg : args) + { + AppletSecurityContextManager.getSecurityContext(0).store(arg); + argIDs += AppletSecurityContextManager.getSecurityContext(0).getIdentifier(arg) + " "; + } + argIDs = argIDs.trim(); // Prefix with dummy instance for convenience. PluginCallRequest request = requestFactory.getPluginCallRequest("member", - "instance " + 0 + " Call " + internal + " " + nameID + " " + argsID, + "instance " + 0 + " Call " + internal + " " + nameID + " " + argIDs, "JavaScriptCall"); streamhandler.postCallRequest(request); streamhandler.write(request.getMessage());
--- a/plugin/icedteanp/java/sun/applet/PluginCookieInfoRequest.java Thu Aug 06 10:43:31 2009 -0400 +++ b/plugin/icedteanp/java/sun/applet/PluginCookieInfoRequest.java Fri Aug 14 15:58:23 2009 -0400 @@ -91,15 +91,20 @@ String cookie = cookies[i]; cookie = cookie.trim(); - String cookieName = cookie.substring(0, cookie.indexOf("=")); - String cookieValue = cookie.substring(cookie.indexOf("=")+1); + 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 + 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); + PluginDebug.debug("Adding cookie info COOKIEN=" + cookieName + " and COOKIEV=" + cookieValue); + cookieObjects.add(httpCookieObj); + } } }