// Invoke a script callback to get a script NPObject. Then call a method on the // script NPObject passing it a freshly created NPObject. static bool testScriptObjectInvoke(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result) { if (argCount != 2 || !NPVARIANT_IS_STRING(args[0]) || !NPVARIANT_IS_STRING(args[1])) return false; NPObject* windowScriptObject; browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject); // Arg1 is the name of the callback NPUTF8* callbackString = createCStringFromNPVariant(&args[0]); NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString); free(callbackString); // Invoke a callback that returns a script object NPVariant object_result; browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, &args[1], 1, &object_result); // Script object returned NPObject* script_object = object_result.value.objectValue; // Arg2 is the name of the method to be called on the script object NPUTF8* object_mehod_string = createCStringFromNPVariant(&args[1]); NPIdentifier object_method = browser->getstringidentifier(object_mehod_string); free(object_mehod_string); // Create a fresh NPObject to be passed as an argument NPObject* object_arg = browser->createobject(obj->npp, &pluginClass); NPVariant invoke_args[1]; OBJECT_TO_NPVARIANT(object_arg, invoke_args[0]); // Invoke the script method NPVariant object_method_result; browser->invoke(obj->npp, script_object, object_method, invoke_args, 1, &object_method_result); browser->releasevariantvalue(&object_result); VOID_TO_NPVARIANT(*result); if (NPVARIANT_IS_OBJECT(object_method_result)) { // Now return the callbacks return value back to our caller. // BUG 897451: This should be the same as the // windowScriptObject, but its not (in Chrome) - or at least, it // has a different refcount. This means Chrome will delete the // object before returning it and the calling JS gets a garbage // value. Firefox handles it fine. OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(object_method_result), *result); } else { browser->releasevariantvalue(&object_method_result); VOID_TO_NPVARIANT(*result); } browser->releaseobject(object_arg); return true; }
static bool testGetProperty(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result) { if (!argCount) return false; NPObject* object; browser->getvalue(obj->npp, NPNVWindowNPObject, &object); for (uint32_t i = 0; i < argCount; i++) { assert(NPVARIANT_IS_STRING(args[i])); NPUTF8* propertyString = createCStringFromNPVariant(&args[i]); NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString); free(propertyString); NPVariant variant; bool retval = browser->getproperty(obj->npp, object, propertyIdentifier, &variant); browser->releaseobject(object); if (!retval) break; if (i + 1 < argCount) { assert(NPVARIANT_IS_OBJECT(variant)); object = NPVARIANT_TO_OBJECT(variant); } else { *result = variant; return true; } } VOID_TO_NPVARIANT(*result); return false; }
static bool testCallbackReturn(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result) { if (argCount != 1 || !NPVARIANT_IS_STRING(args[0])) return false; NPObject* windowScriptObject; browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject); NPUTF8* callbackString = createCStringFromNPVariant(&args[0]); NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString); free(callbackString); NPVariant callbackArgs[1]; OBJECT_TO_NPVARIANT(windowScriptObject, callbackArgs[0]); NPVariant browserResult; browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, callbackArgs, 1, &browserResult); if (NPVARIANT_IS_OBJECT(browserResult)) OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(browserResult), *result); else { browser->releasevariantvalue(&browserResult); VOID_TO_NPVARIANT(*result); } return true; }
NPIdentifier stringVariantToIdentifier(NPVariant variant) { assert(NPVARIANT_IS_STRING(variant)); NPUTF8* utf8String = createCStringFromNPVariant(&variant); NPIdentifier identifier = NPN_GetStringIdentifier(utf8String); free(utf8String); return identifier; }
static NPIdentifier stringVariantToIdentifier(NPVariant variant) { assert(NPVARIANT_IS_STRING(variant)); NPUTF8* utf8String = createCStringFromNPVariant(&variant); NPIdentifier identifier = browser->getstringidentifier(utf8String); free(utf8String); return identifier; }
static bool getURLNotify(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result) { if (argCount != 3 || !NPVARIANT_IS_STRING(args[0]) || (!NPVARIANT_IS_STRING(args[1]) && !NPVARIANT_IS_NULL(args[1])) || !NPVARIANT_IS_STRING(args[2])) return false; NPUTF8* urlString = createCStringFromNPVariant(&args[0]); NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : 0); NPUTF8* callbackString = createCStringFromNPVariant(&args[2]); NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString); browser->geturlnotify(obj->npp, urlString, targetString, callbackIdentifier); free(urlString); free(targetString); free(callbackString); VOID_TO_NPVARIANT(*result); return true; }
static bool getURL(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result) { if (argCount == 2 && NPVARIANT_IS_STRING(args[0]) && NPVARIANT_IS_STRING(args[1])) { NPUTF8* urlString = createCStringFromNPVariant(&args[0]); NPUTF8* targetString = createCStringFromNPVariant(&args[1]); NPError npErr = browser->geturl(obj->npp, urlString, targetString); free(urlString); free(targetString); INT32_TO_NPVARIANT(npErr, *result); return true; } else if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) { NPUTF8* urlString = createCStringFromNPVariant(&args[0]); NPError npErr = browser->geturl(obj->npp, urlString, 0); free(urlString); INT32_TO_NPVARIANT(npErr, *result); return true; } return false; }
static bool testHasMethod(PluginObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result) { if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) || !NPVARIANT_IS_STRING(args[1])) return false; NPUTF8* propertyString = createCStringFromNPVariant(&args[1]); NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString); free(propertyString); bool retval = browser->hasmethod(obj->npp, NPVARIANT_TO_OBJECT(args[0]), propertyIdentifier); BOOLEAN_TO_NPVARIANT(retval, *result); return true; }
static bool pluginInvoke(NPObject *header, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result) { PluginObject *obj = (PluginObject *)header; if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD]) { // call whatever method name we're given if (argCount > 0 && NPVARIANT_IS_STRING(args[0])) { NPObject *windowScriptObject; browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject); NPUTF8* callbackString = createCStringFromNPVariant(&args[0]); NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString); free(callbackString); NPVariant browserResult; browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, 0, 0, &browserResult); browser->releasevariantvalue(&browserResult); VOID_TO_NPVARIANT(*result); return true; } } else if (name == pluginMethodIdentifiers[ID_TEST_GETURL]) { if (argCount == 2 && NPVARIANT_IS_STRING(args[0]) && NPVARIANT_IS_STRING(args[1])) { NPUTF8* urlString = createCStringFromNPVariant(&args[0]); NPUTF8* targetString = createCStringFromNPVariant(&args[1]); browser->geturl(obj->npp, urlString, targetString); free(urlString); free(targetString); VOID_TO_NPVARIANT(*result); return true; } else if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) { NPUTF8* urlString = createCStringFromNPVariant(&args[0]); browser->geturl(obj->npp, urlString, 0); free(urlString); VOID_TO_NPVARIANT(*result); return true; } } else if (name == pluginMethodIdentifiers[ID_REMOVE_DEFAULT_METHOD]) { pluginClass.invokeDefault = 0; VOID_TO_NPVARIANT(*result); return true; } else if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS]) { testDOMAccess(obj); VOID_TO_NPVARIANT(*result); return true; } else if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY]) { if (argCount == 3 && NPVARIANT_IS_STRING(args[0]) && (NPVARIANT_IS_STRING(args[1]) || NPVARIANT_IS_NULL(args[1])) && NPVARIANT_IS_STRING(args[2])) { NPUTF8* urlString = createCStringFromNPVariant(&args[0]); NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : NULL); NPUTF8* callbackString = createCStringFromNPVariant(&args[2]); NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString); browser->geturlnotify(obj->npp, urlString, targetString, callbackIdentifier); free(urlString); free(targetString); free(callbackString); VOID_TO_NPVARIANT(*result); return true; } } else if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT] && NPVARIANT_IS_OBJECT(args[0])) { NPObject *callback = NPVARIANT_TO_OBJECT(args[0]); NPVariant args[1]; NPVariant browserResult; STRINGZ_TO_NPVARIANT("test", args[0]); bool retval = browser->invokeDefault(obj->npp, callback, args, 1, &browserResult); if (retval) browser->releasevariantvalue(&browserResult); BOOLEAN_TO_NPVARIANT(retval, *result); return true; } else if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE]) { if (argCount == 2 && NPVARIANT_IS_OBJECT(args[0]) && NPVARIANT_IS_OBJECT(args[1])) { uint32_t count; NPIdentifier* identifiers; if (browser->enumerate(obj->npp, NPVARIANT_TO_OBJECT(args[0]), &identifiers, &count)) { NPObject* outArray = NPVARIANT_TO_OBJECT(args[1]); NPIdentifier pushIdentifier = browser->getstringidentifier("push"); for (uint32_t i = 0; i < count; i++) { NPUTF8* string = browser->utf8fromidentifier(identifiers[i]); if (!string) continue; NPVariant args[1]; STRINGZ_TO_NPVARIANT(string, args[0]); NPVariant browserResult; browser->invoke(obj->npp, outArray, pushIdentifier, args, 1, &browserResult); browser->releasevariantvalue(&browserResult); browser->memfree(string); } browser->memfree(identifiers); } VOID_TO_NPVARIANT(*result); return true; } return false; } else if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM]) { NPError npError = browser->destroystream(obj->npp, obj->stream, NPRES_USER_BREAK); INT32_TO_NPVARIANT(npError, *result); return true; } else if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER]) { if (argCount == 1) { NPIdentifier identifier; if (NPVARIANT_IS_DOUBLE(args[0])) { identifier = browser->getintidentifier((int)NPVARIANT_TO_DOUBLE(args[0])); INT32_TO_NPVARIANT((int32)identifier, *result); return true; } else if (NPVARIANT_IS_INT32(args[0])) { identifier = browser->getintidentifier((int)NPVARIANT_TO_INT32(args[0])); INT32_TO_NPVARIANT((int32)identifier, *result); return true; } } } else if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE] && argCount == 1 && NPVARIANT_IS_STRING(args[0])) { NPObject *windowScriptObject; browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject); NPString s = NPVARIANT_TO_STRING(args[0]); bool retval = browser->evaluate(obj->npp, windowScriptObject, &s, result); browser->releaseobject(windowScriptObject); return retval; } else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY] && argCount > 0) { NPObject *object; browser->getvalue(obj->npp, NPNVWindowNPObject, &object); for (uint32_t i = 0; i < argCount; i++) { //assert(NPVARIANT_IS_STRING(args[i])); NPUTF8* propertyString = createCStringFromNPVariant(&args[i]); NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString); free(propertyString); NPVariant variant; bool retval = browser->getproperty(obj->npp, object, propertyIdentifier, &variant); browser->releaseobject(object); if (!retval) break; if (i + 1 < argCount) { //assert(NPVARIANT_IS_OBJECT(variant)); object = NPVARIANT_TO_OBJECT(variant); } else { *result = variant; return true; } } VOID_TO_NPVARIANT(*result); return false; } else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY_RETURN_VALUE] && argCount == 2 && NPVARIANT_IS_OBJECT(args[0]) && NPVARIANT_IS_STRING(args[1])) { NPUTF8* propertyString = createCStringFromNPVariant(&args[1]); NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString); free(propertyString); NPVariant variant; bool retval = browser->getproperty(obj->npp, NPVARIANT_TO_OBJECT(args[0]), propertyIdentifier, &variant); if (retval) browser->releasevariantvalue(&variant); BOOLEAN_TO_NPVARIANT(retval, *result); return true; } else if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD_RET]) { // call whatever method name we're given, and pass it the 'window' obj. // we expect the function to return its argument. if (argCount > 0 && NPVARIANT_IS_STRING(args[0])) { NPObject *windowScriptObject; browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject); NPUTF8* callbackString = createCStringFromNPVariant(&args[0]); NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString); free(callbackString); NPVariant callbackArgs[1]; OBJECT_TO_NPVARIANT(windowScriptObject, callbackArgs[0]); NPVariant browserResult; browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, callbackArgs, 1, &browserResult); if (NPVARIANT_IS_OBJECT(browserResult)) { // Now return the callbacks return value back to our caller. // BUG 897451: This should be the same as the // windowScriptObject, but its not (in Chrome) - or at least, it // has a different refcount. This means Chrome will delete the // object before returning it and the calling JS gets a garbage // value. Firefox handles it fine. OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(browserResult), *result); } else { browser->releasevariantvalue(&browserResult); VOID_TO_NPVARIANT(*result); } return true; } } else if (name == pluginMethodIdentifiers[ID_TEST_CREATE_TEST_OBJECT]) { NPObject *testObject = browser->createobject(obj->npp, getTestClass()); //assert(testObject->referenceCount == 1); OBJECT_TO_NPVARIANT(testObject, *result); return true; } else if (name == pluginMethodIdentifiers[ID_TEST_PASS_TEST_OBJECT]) { // call whatever method name we're given, and pass it our second // argument. if (argCount > 1 && NPVARIANT_IS_STRING(args[0])) { NPObject *windowScriptObject; browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject); NPUTF8* callbackString = createCStringFromNPVariant(&args[0]); NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString); free(callbackString); NPVariant browserResult; browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, &args[1], 1, &browserResult); browser->releasevariantvalue(&browserResult); VOID_TO_NPVARIANT(*result); return true; } } else if (name == pluginMethodIdentifiers[ID_TEST_CLONE_OBJECT]) { // Create another instance of the same class NPObject *new_object = browser->createobject(obj->npp, &pluginClass); //assert(new_object->referenceCount == 1); OBJECT_TO_NPVARIANT(new_object, *result); return true; } else if (name == pluginMethodIdentifiers[ID_TEST_SCRIPT_OBJECT_INVOKE]) { if (argCount > 1 && NPVARIANT_IS_STRING(args[0])) { // Invoke a script callback to get a script NPObject. Then call // a method on the script NPObject passing it a freshly created // NPObject. // Arguments: // arg1: Callback that returns a script object. // arg2: Name of the method to call on the script object returned // from the callback NPObject *windowScriptObject; browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject); // Arg1 is the name of the callback NPUTF8* callbackString = createCStringFromNPVariant(&args[0]); NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString); free(callbackString); // Invoke a callback that returns a script object NPVariant object_result; browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, &args[1], 1, &object_result); // Script object returned NPObject *script_object = object_result.value.objectValue; // Arg2 is the name of the method to be called on the script object NPUTF8* object_mehod_string = createCStringFromNPVariant(&args[1]); NPIdentifier object_method = browser->getstringidentifier(object_mehod_string); free(object_mehod_string); // Create a fresh NPObject to be passed as an argument NPObject *object_arg = browser->createobject(obj->npp, &pluginClass); NPVariant invoke_args[1]; OBJECT_TO_NPVARIANT(object_arg, invoke_args[0]); // Invoke the script method NPVariant object_method_result; browser->invoke(obj->npp, script_object, object_method, invoke_args, 1, &object_method_result); browser->releasevariantvalue(&object_result); VOID_TO_NPVARIANT(*result); if (NPVARIANT_IS_OBJECT(object_method_result)) { // Now return the callbacks return value back to our caller. // BUG 897451: This should be the same as the // windowScriptObject, but its not (in Chrome) - or at least, it // has a different refcount. This means Chrome will delete the // object before returning it and the calling JS gets a garbage // value. Firefox handles it fine. OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(object_method_result), *result); } else { browser->releasevariantvalue(&object_method_result); VOID_TO_NPVARIANT(*result); } return true; } } return false; }