| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions | |
| 6 * are met: | |
| 7 * 1. Redistributions of source code must retain the above copyright | |
| 8 * notice, this list of conditions and the following disclaimer. | |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | |
| 10 * notice, this list of conditions and the following disclaimer in the | |
| 11 * documentation and/or other materials provided with the distribution. | |
| 12 * | |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY | |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR | |
| 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
| 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
| 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 24 */ | |
| 25 | |
| 26 #include "PluginObject.h" | |
| 27 | |
| 28 #include "TestObject.h" | |
| 29 #include <assert.h> | |
| 30 #include <stdlib.h> | |
| 31 #include <stdio.h> | |
| 32 #include <string.h> | |
| 33 #ifdef WIN32 | |
| 34 #define snprintf sprintf_s | |
| 35 #endif | |
| 36 | |
| 37 static void logWithWindowObject(NPObject* windowObject, NPP instance, const char
* message) | |
| 38 { | |
| 39 NPVariant consoleVariant; | |
| 40 if (!browser->getproperty(instance, windowObject, browser->getstringidentifi
er("console"), &consoleVariant)) { | |
| 41 fprintf(stderr, "Failed to retrieve console object while logging: %s\n",
message); | |
| 42 return; | |
| 43 } | |
| 44 | |
| 45 NPObject* consoleObject = NPVARIANT_TO_OBJECT(consoleVariant); | |
| 46 | |
| 47 NPVariant messageVariant; | |
| 48 STRINGZ_TO_NPVARIANT(message, messageVariant); | |
| 49 | |
| 50 NPVariant result; | |
| 51 if (!browser->invoke(instance, consoleObject, browser->getstringidentifier("
log"), &messageVariant, 1, &result)) { | |
| 52 fprintf(stderr, "Failed to invoke console.log while logging: %s\n", mess
age); | |
| 53 browser->releaseobject(consoleObject); | |
| 54 return; | |
| 55 } | |
| 56 | |
| 57 browser->releasevariantvalue(&result); | |
| 58 browser->releaseobject(consoleObject); | |
| 59 } | |
| 60 | |
| 61 static void logWithWindowObjectVariableArgs(NPObject* windowObject, NPP instance
, const char* format, ...) | |
| 62 { | |
| 63 va_list args; | |
| 64 va_start(args, format); | |
| 65 char message[2048] = "PLUGIN: "; | |
| 66 vsprintf(message + strlen(message), format, args); | |
| 67 va_end(args); | |
| 68 | |
| 69 logWithWindowObject(windowObject, instance, message); | |
| 70 } | |
| 71 | |
| 72 void log(NPP instance, const char* format, ...) | |
| 73 { | |
| 74 va_list args; | |
| 75 va_start(args, format); | |
| 76 char message[2048] = "PLUGIN: "; | |
| 77 vsprintf(message + strlen(message), format, args); | |
| 78 va_end(args); | |
| 79 | |
| 80 NPObject* windowObject = 0; | |
| 81 NPError error = browser->getvalue(instance, NPNVWindowNPObject, &windowObjec
t); | |
| 82 if (error != NPERR_NO_ERROR) { | |
| 83 fprintf(stderr, "Failed to retrieve window object while logging: %s\n",
message); | |
| 84 return; | |
| 85 } | |
| 86 | |
| 87 logWithWindowObject(windowObject, instance, message); | |
| 88 browser->releaseobject(windowObject); | |
| 89 } | |
| 90 | |
| 91 static void pluginInvalidate(NPObject*); | |
| 92 static bool pluginHasProperty(NPObject*, NPIdentifier name); | |
| 93 static bool pluginHasMethod(NPObject*, NPIdentifier name); | |
| 94 static bool pluginGetProperty(NPObject*, NPIdentifier name, NPVariant*); | |
| 95 static bool pluginSetProperty(NPObject*, NPIdentifier name, const NPVariant*); | |
| 96 static bool pluginInvoke(NPObject*, NPIdentifier name, const NPVariant* args, ui
nt32_t argCount, NPVariant* result); | |
| 97 static bool pluginInvokeDefault(NPObject*, const NPVariant* args, uint32_t argCo
unt, NPVariant* result); | |
| 98 static NPObject* pluginAllocate(NPP npp, NPClass*); | |
| 99 static void pluginDeallocate(NPObject*); | |
| 100 | |
| 101 NPNetscapeFuncs* browser; | |
| 102 | |
| 103 static NPClass pluginClass = { | |
| 104 NP_CLASS_STRUCT_VERSION, | |
| 105 pluginAllocate, | |
| 106 pluginDeallocate, | |
| 107 pluginInvalidate, | |
| 108 pluginHasMethod, | |
| 109 pluginInvoke, | |
| 110 pluginInvokeDefault, | |
| 111 pluginHasProperty, | |
| 112 pluginGetProperty, | |
| 113 pluginSetProperty, | |
| 114 }; | |
| 115 | |
| 116 NPClass *getPluginClass(void) | |
| 117 { | |
| 118 return &pluginClass; | |
| 119 } | |
| 120 | |
| 121 static bool identifiersInitialized = false; | |
| 122 | |
| 123 #define ID_PROPERTY_PROPERTY 0 | |
| 124 #define ID_PROPERTY_EVENT_LOGGING 1 | |
| 125 #define ID_PROPERTY_HAS_STREAM 2 | |
| 126 #define ID_PROPERTY_TEST_OBJECT 3 | |
| 127 #define ID_PROPERTY_LOG_DESTROY 4 | |
| 128 #define ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM 5 | |
| 129 #define ID_PROPERTY_TEST_OBJECT_COUNT 6 | |
| 130 #define ID_PROPERTY_THROW_EXCEPTION_PROPERTY 7 | |
| 131 #define NUM_PROPERTY_IDENTIFIERS 8 | |
| 132 | |
| 133 static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS]; | |
| 134 static const NPUTF8 *pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = { | |
| 135 "property", | |
| 136 "eventLoggingEnabled", | |
| 137 "hasStream", | |
| 138 "testObject", | |
| 139 "logDestroy", | |
| 140 "returnErrorFromNewStream", | |
| 141 "testObjectCount", | |
| 142 "testThrowExceptionProperty", | |
| 143 }; | |
| 144 | |
| 145 enum { | |
| 146 ID_TEST_CALLBACK_METHOD = 0, | |
| 147 ID_TEST_GETURL, | |
| 148 ID_REMOVE_DEFAULT_METHOD, | |
| 149 ID_TEST_DOM_ACCESS, | |
| 150 ID_TEST_GET_URL_NOTIFY, | |
| 151 ID_TEST_INVOKE_DEFAULT, | |
| 152 ID_DESTROY_STREAM, | |
| 153 ID_TEST_ENUMERATE, | |
| 154 ID_TEST_GETINTIDENTIFIER, | |
| 155 ID_TEST_GET_PROPERTY, | |
| 156 ID_TEST_EVALUATE, | |
| 157 ID_TEST_GET_PROPERTY_RETURN_VALUE, | |
| 158 ID_TEST_CALLBACK_METHOD_RET, | |
| 159 ID_TEST_CALLBACK_METHOD_RETURN, | |
| 160 ID_TEST_CREATE_TEST_OBJECT, | |
| 161 ID_TEST_PASS_TEST_OBJECT, | |
| 162 ID_TEST_CLONE_OBJECT, | |
| 163 ID_TEST_SCRIPT_OBJECT_INVOKE, | |
| 164 ID_TEST_IDENTIFIER_TO_STRING, | |
| 165 ID_TEST_IDENTIFIER_TO_INT, | |
| 166 ID_TEST_POSTURL_FILE, | |
| 167 ID_TEST_CALLBACK_AND_GET_VALUE, | |
| 168 ID_TEST_CONSTRUCT, | |
| 169 ID_DESTROY_NULL_STREAM, | |
| 170 ID_TEST_HAS_PROPERTY, | |
| 171 ID_TEST_HAS_METHOD, | |
| 172 ID_TEST_THROW_EXCEPTION_METHOD, | |
| 173 ID_TEST_FAIL_METHOD, | |
| 174 ID_TEST_GET_BROWSER_PROPERTY, | |
| 175 ID_TEST_SET_BROWSER_PROPERTY, | |
| 176 NUM_METHOD_IDENTIFIERS | |
| 177 }; | |
| 178 | |
| 179 static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS]; | |
| 180 static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = { | |
| 181 "testCallback", | |
| 182 "getURL", | |
| 183 "removeDefaultMethod", | |
| 184 "testDOMAccess", | |
| 185 "getURLNotify", | |
| 186 "testInvokeDefault", | |
| 187 "destroyStream", | |
| 188 "testEnumerate", | |
| 189 "testGetIntIdentifier", | |
| 190 "testGetProperty", | |
| 191 "testEvaluate", | |
| 192 "testGetPropertyReturnValue", | |
| 193 "testCallbackRet", // Chrome bug 897451 | |
| 194 "testCallbackReturn", // Chrome bug 897451 | |
| 195 "testCreateTestObject", // Chrome bug 1093606 | |
| 196 "testPassTestObject", // Chrome bug 1093606 | |
| 197 "testCloneObject", | |
| 198 "testScriptObjectInvoke", // Chrome bug 1175346 | |
| 199 "testIdentifierToString", | |
| 200 "testIdentifierToInt", | |
| 201 "testPostURLFile", | |
| 202 // Chrome bug http://code.google.com/p/chromium/issues/detail?id=4270 | |
| 203 "testCallbackAndGetValue", | |
| 204 "testConstruct", | |
| 205 "destroyNullStream", | |
| 206 "testHasProperty", | |
| 207 "testHasMethod", | |
| 208 "testThrowException", | |
| 209 "testFail", | |
| 210 "testGetBrowserProperty", | |
| 211 "testSetBrowserProperty" | |
| 212 }; | |
| 213 | |
| 214 static NPUTF8* createCStringFromNPVariant(const NPVariant* variant) | |
| 215 { | |
| 216 size_t length = NPVARIANT_TO_STRING(*variant).UTF8Length; | |
| 217 NPUTF8* result = (NPUTF8*)malloc(length + 1); | |
| 218 memcpy(result, NPVARIANT_TO_STRING(*variant).UTF8Characters, length); | |
| 219 result[length] = '\0'; | |
| 220 return result; | |
| 221 } | |
| 222 | |
| 223 static void initializeIdentifiers(void) | |
| 224 { | |
| 225 browser->getstringidentifiers(pluginPropertyIdentifierNames, NUM_PROPERTY_ID
ENTIFIERS, pluginPropertyIdentifiers); | |
| 226 browser->getstringidentifiers(pluginMethodIdentifierNames, NUM_METHOD_IDENTI
FIERS, pluginMethodIdentifiers); | |
| 227 } | |
| 228 | |
| 229 static bool pluginHasProperty(NPObject *obj, NPIdentifier name) | |
| 230 { | |
| 231 for (int i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++) | |
| 232 if (name == pluginPropertyIdentifiers[i]) | |
| 233 return true; | |
| 234 return false; | |
| 235 } | |
| 236 | |
| 237 static bool pluginHasMethod(NPObject *obj, NPIdentifier name) | |
| 238 { | |
| 239 for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++) | |
| 240 if (name == pluginMethodIdentifiers[i]) | |
| 241 return true; | |
| 242 return false; | |
| 243 } | |
| 244 | |
| 245 static bool pluginGetProperty(NPObject* obj, NPIdentifier name, NPVariant* resul
t) | |
| 246 { | |
| 247 PluginObject* plugin = reinterpret_cast<PluginObject*>(obj); | |
| 248 if (name == pluginPropertyIdentifiers[ID_PROPERTY_PROPERTY]) { | |
| 249 static const char* originalString = "property"; | |
| 250 char* buf = static_cast<char*>(browser->memalloc(strlen(originalString)
+ 1)); | |
| 251 strcpy(buf, originalString); | |
| 252 STRINGZ_TO_NPVARIANT(buf, *result); | |
| 253 return true; | |
| 254 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) { | |
| 255 BOOLEAN_TO_NPVARIANT(plugin->eventLogging, *result); | |
| 256 return true; | |
| 257 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) { | |
| 258 BOOLEAN_TO_NPVARIANT(plugin->logDestroy, *result); | |
| 259 return true; | |
| 260 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) { | |
| 261 BOOLEAN_TO_NPVARIANT(plugin->stream != 0, *result); | |
| 262 return true; | |
| 263 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT]) { | |
| 264 NPObject* testObject = plugin->testObject; | |
| 265 browser->retainobject(testObject); | |
| 266 OBJECT_TO_NPVARIANT(testObject, *result); | |
| 267 return true; | |
| 268 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_N
EWSTREAM]) { | |
| 269 BOOLEAN_TO_NPVARIANT(plugin->returnErrorFromNewStream, *result); | |
| 270 return true; | |
| 271 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT_COUNT])
{ | |
| 272 INT32_TO_NPVARIANT(getTestObjectCount(), *result); | |
| 273 return true; | |
| 274 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PRO
PERTY]) { | |
| 275 browser->setexception(obj, "plugin object testThrowExceptionProperty SUC
CESS"); | |
| 276 return true; | |
| 277 } | |
| 278 return false; | |
| 279 } | |
| 280 | |
| 281 static bool pluginSetProperty(NPObject* obj, NPIdentifier name, const NPVariant*
variant) | |
| 282 { | |
| 283 PluginObject* plugin = reinterpret_cast<PluginObject*>(obj); | |
| 284 if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) { | |
| 285 plugin->eventLogging = NPVARIANT_TO_BOOLEAN(*variant); | |
| 286 return true; | |
| 287 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) { | |
| 288 plugin->logDestroy = NPVARIANT_TO_BOOLEAN(*variant); | |
| 289 return true; | |
| 290 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_N
EWSTREAM]) { | |
| 291 plugin->returnErrorFromNewStream = NPVARIANT_TO_BOOLEAN(*variant); | |
| 292 return true; | |
| 293 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PRO
PERTY]) { | |
| 294 browser->setexception(obj, "plugin object testThrowExceptionProperty SUC
CESS"); | |
| 295 return true; | |
| 296 } | |
| 297 | |
| 298 return false; | |
| 299 } | |
| 300 | |
| 301 static bool testDOMAccess(PluginObject* obj, const NPVariant*, uint32_t, NPVaria
nt* result) | |
| 302 { | |
| 303 // Get plug-in's DOM element | |
| 304 NPObject* elementObject; | |
| 305 if (browser->getvalue(obj->npp, NPNVPluginElementNPObject, &elementObject) =
= NPERR_NO_ERROR) { | |
| 306 // Get style | |
| 307 NPVariant styleVariant; | |
| 308 NPIdentifier styleIdentifier = browser->getstringidentifier("style"); | |
| 309 if (browser->getproperty(obj->npp, elementObject, styleIdentifier, &styl
eVariant) && NPVARIANT_IS_OBJECT(styleVariant)) { | |
| 310 // Set style.border | |
| 311 NPIdentifier borderIdentifier = browser->getstringidentifier("border
"); | |
| 312 NPVariant borderVariant; | |
| 313 STRINGZ_TO_NPVARIANT("3px solid red", borderVariant); | |
| 314 browser->setproperty(obj->npp, NPVARIANT_TO_OBJECT(styleVariant), bo
rderIdentifier, &borderVariant); | |
| 315 browser->releasevariantvalue(&styleVariant); | |
| 316 } | |
| 317 | |
| 318 browser->releaseobject(elementObject); | |
| 319 } | |
| 320 VOID_TO_NPVARIANT(*result); | |
| 321 return true; | |
| 322 } | |
| 323 | |
| 324 static NPIdentifier stringVariantToIdentifier(NPVariant variant) | |
| 325 { | |
| 326 assert(NPVARIANT_IS_STRING(variant)); | |
| 327 NPUTF8* utf8String = createCStringFromNPVariant(&variant); | |
| 328 NPIdentifier identifier = browser->getstringidentifier(utf8String); | |
| 329 free(utf8String); | |
| 330 return identifier; | |
| 331 } | |
| 332 | |
| 333 static NPIdentifier int32VariantToIdentifier(NPVariant variant) | |
| 334 { | |
| 335 assert(NPVARIANT_IS_INT32(variant)); | |
| 336 int32_t integer = NPVARIANT_TO_INT32(variant); | |
| 337 return browser->getintidentifier(integer); | |
| 338 } | |
| 339 | |
| 340 static NPIdentifier doubleVariantToIdentifier(NPVariant variant) | |
| 341 { | |
| 342 assert(NPVARIANT_IS_DOUBLE(variant)); | |
| 343 double value = NPVARIANT_TO_DOUBLE(variant); | |
| 344 // Sadly there is no "getdoubleidentifier" | |
| 345 int32_t integer = static_cast<int32_t>(value); | |
| 346 return browser->getintidentifier(integer); | |
| 347 } | |
| 348 | |
| 349 static NPIdentifier variantToIdentifier(NPVariant variant) | |
| 350 { | |
| 351 if (NPVARIANT_IS_STRING(variant)) | |
| 352 return stringVariantToIdentifier(variant); | |
| 353 else if (NPVARIANT_IS_INT32(variant)) | |
| 354 return int32VariantToIdentifier(variant); | |
| 355 else if (NPVARIANT_IS_DOUBLE(variant)) | |
| 356 return doubleVariantToIdentifier(variant); | |
| 357 return 0; | |
| 358 } | |
| 359 | |
| 360 static bool testIdentifierToString(PluginObject*, const NPVariant* args, uint32_
t argCount, NPVariant* result) | |
| 361 { | |
| 362 if (argCount != 1) | |
| 363 return true; | |
| 364 NPIdentifier identifier = variantToIdentifier(args[0]); | |
| 365 if (!identifier) | |
| 366 return true; | |
| 367 NPUTF8* utf8String = browser->utf8fromidentifier(identifier); | |
| 368 if (!utf8String) | |
| 369 return true; | |
| 370 STRINGZ_TO_NPVARIANT(utf8String, *result); | |
| 371 return true; | |
| 372 } | |
| 373 | |
| 374 static bool testIdentifierToInt(PluginObject*, const NPVariant* args, uint32_t a
rgCount, NPVariant* result) | |
| 375 { | |
| 376 if (argCount != 1) | |
| 377 return false; | |
| 378 NPIdentifier identifier = variantToIdentifier(args[0]); | |
| 379 if (!identifier) | |
| 380 return false; | |
| 381 int32_t integer = browser->intfromidentifier(identifier); | |
| 382 INT32_TO_NPVARIANT(integer, *result); | |
| 383 return true; | |
| 384 } | |
| 385 | |
| 386 static bool testCallback(PluginObject* obj, const NPVariant* args, uint32_t argC
ount, NPVariant* result) | |
| 387 { | |
| 388 if (argCount == 0 || !NPVARIANT_IS_STRING(args[0])) | |
| 389 return false; | |
| 390 | |
| 391 NPObject* windowScriptObject; | |
| 392 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject); | |
| 393 | |
| 394 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]); | |
| 395 NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackStrin
g); | |
| 396 free(callbackString); | |
| 397 | |
| 398 NPVariant browserResult; | |
| 399 browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, 0, 0, &bro
wserResult); | |
| 400 browser->releasevariantvalue(&browserResult); | |
| 401 | |
| 402 VOID_TO_NPVARIANT(*result); | |
| 403 return true; | |
| 404 } | |
| 405 | |
| 406 static bool testCallbackAndGetValue(PluginObject* obj, const NPVariant* args, ui
nt32_t argCount, NPVariant* result) | |
| 407 { | |
| 408 NPP npp = obj->npp; | |
| 409 if (!testCallback(obj, args, argCount, result)) | |
| 410 return false; | |
| 411 | |
| 412 NPObject *global; | |
| 413 browser->getvalue(npp, NPNVWindowNPObject, &global); | |
| 414 | |
| 415 VOID_TO_NPVARIANT(*result); | |
| 416 return true; | |
| 417 } | |
| 418 | |
| 419 static bool getURL(PluginObject* obj, const NPVariant* args, uint32_t argCount,
NPVariant* result) | |
| 420 { | |
| 421 if (argCount == 2 && NPVARIANT_IS_STRING(args[0]) && NPVARIANT_IS_STRING(arg
s[1])) { | |
| 422 NPUTF8* urlString = createCStringFromNPVariant(&args[0]); | |
| 423 NPUTF8* targetString = createCStringFromNPVariant(&args[1]); | |
| 424 NPError npErr = browser->geturl(obj->npp, urlString, targetString); | |
| 425 free(urlString); | |
| 426 free(targetString); | |
| 427 | |
| 428 INT32_TO_NPVARIANT(npErr, *result); | |
| 429 return true; | |
| 430 } else if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) { | |
| 431 NPUTF8* urlString = createCStringFromNPVariant(&args[0]); | |
| 432 NPError npErr = browser->geturl(obj->npp, urlString, 0); | |
| 433 free(urlString); | |
| 434 | |
| 435 INT32_TO_NPVARIANT(npErr, *result); | |
| 436 return true; | |
| 437 } | |
| 438 return false; | |
| 439 } | |
| 440 | |
| 441 static bool removeDefaultMethod(PluginObject*, const NPVariant* args, uint32_t a
rgCount, NPVariant* result) | |
| 442 { | |
| 443 pluginClass.invokeDefault = 0; | |
| 444 VOID_TO_NPVARIANT(*result); | |
| 445 return true; | |
| 446 } | |
| 447 | |
| 448 static bool getURLNotify(PluginObject* obj, const NPVariant* args, uint32_t argC
ount, NPVariant* result) | |
| 449 { | |
| 450 if (argCount != 3 || !NPVARIANT_IS_STRING(args[0]) | |
| 451 || (!NPVARIANT_IS_STRING(args[1]) && !NPVARIANT_IS_NULL(args[1])) | |
| 452 || !NPVARIANT_IS_STRING(args[2])) | |
| 453 return false; | |
| 454 | |
| 455 NPUTF8* urlString = createCStringFromNPVariant(&args[0]); | |
| 456 NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVa
riant(&args[1]) : NULL); | |
| 457 NPUTF8* callbackString = createCStringFromNPVariant(&args[2]); | |
| 458 | |
| 459 NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackStrin
g); | |
| 460 browser->geturlnotify(obj->npp, urlString, targetString, callbackIdentifier)
; | |
| 461 | |
| 462 free(urlString); | |
| 463 free(targetString); | |
| 464 free(callbackString); | |
| 465 | |
| 466 VOID_TO_NPVARIANT(*result); | |
| 467 return true; | |
| 468 } | |
| 469 | |
| 470 static bool testInvokeDefault(PluginObject* obj, const NPVariant* args, uint32_t
argCount, NPVariant* result) | |
| 471 { | |
| 472 if (!NPVARIANT_IS_OBJECT(args[0])) | |
| 473 return false; | |
| 474 | |
| 475 NPObject *callback = NPVARIANT_TO_OBJECT(args[0]); | |
| 476 | |
| 477 NPVariant invokeArgs[1]; | |
| 478 NPVariant browserResult; | |
| 479 | |
| 480 STRINGZ_TO_NPVARIANT("test", invokeArgs[0]); | |
| 481 bool retval = browser->invokeDefault(obj->npp, callback, invokeArgs, 1, &bro
wserResult); | |
| 482 | |
| 483 if (retval) | |
| 484 browser->releasevariantvalue(&browserResult); | |
| 485 | |
| 486 BOOLEAN_TO_NPVARIANT(retval, *result); | |
| 487 return true; | |
| 488 } | |
| 489 | |
| 490 static bool destroyStream(PluginObject* obj, const NPVariant* args, uint32_t arg
Count, NPVariant* result) | |
| 491 { | |
| 492 NPError npError = browser->destroystream(obj->npp, obj->stream, NPRES_USER_B
REAK); | |
| 493 INT32_TO_NPVARIANT(npError, *result); | |
| 494 return true; | |
| 495 } | |
| 496 | |
| 497 static bool destroyNullStream(PluginObject* obj, const NPVariant* args, uint32_t
argCount, NPVariant* result) | |
| 498 { | |
| 499 NPError npError = browser->destroystream(obj->npp, 0, NPRES_USER_BREAK); | |
| 500 INT32_TO_NPVARIANT(npError, *result); | |
| 501 return true; | |
| 502 } | |
| 503 | |
| 504 static bool testHasProperty(PluginObject* obj, const NPVariant* args, uint32_t a
rgCount, NPVariant* result) | |
| 505 { | |
| 506 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) || !NPVARIANT_IS_STRING(a
rgs[1])) | |
| 507 return false; | |
| 508 | |
| 509 NPUTF8* propertyString = createCStringFromNPVariant(&args[1]); | |
| 510 NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyStrin
g); | |
| 511 free(propertyString); | |
| 512 | |
| 513 bool retval = browser->hasproperty(obj->npp, NPVARIANT_TO_OBJECT(args[0]), p
ropertyIdentifier); | |
| 514 | |
| 515 BOOLEAN_TO_NPVARIANT(retval, *result); | |
| 516 return true; | |
| 517 } | |
| 518 | |
| 519 static bool testHasMethod(PluginObject* obj, const NPVariant* args, uint32_t arg
Count, NPVariant* result) | |
| 520 { | |
| 521 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) || !NPVARIANT_IS_STRING(a
rgs[1])) | |
| 522 return false; | |
| 523 | |
| 524 NPUTF8* propertyString = createCStringFromNPVariant(&args[1]); | |
| 525 NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyStrin
g); | |
| 526 free(propertyString); | |
| 527 | |
| 528 bool retval = browser->hasmethod(obj->npp, NPVARIANT_TO_OBJECT(args[0]), pro
pertyIdentifier); | |
| 529 | |
| 530 BOOLEAN_TO_NPVARIANT(retval, *result); | |
| 531 return true; | |
| 532 } | |
| 533 | |
| 534 static bool testEnumerate(PluginObject* obj, const NPVariant* args, uint32_t arg
Count, NPVariant* result) | |
| 535 { | |
| 536 if (argCount == 2 && NPVARIANT_IS_OBJECT(args[0]) && NPVARIANT_IS_OBJECT(arg
s[1])) { | |
| 537 uint32_t count; | |
| 538 NPIdentifier* identifiers; | |
| 539 | |
| 540 if (browser->enumerate(obj->npp, NPVARIANT_TO_OBJECT(args[0]), &identifi
ers, &count)) { | |
| 541 NPObject* outArray = NPVARIANT_TO_OBJECT(args[1]); | |
| 542 NPIdentifier pushIdentifier = browser->getstringidentifier("push"); | |
| 543 | |
| 544 for (uint32_t i = 0; i < count; i++) { | |
| 545 NPUTF8* string = browser->utf8fromidentifier(identifiers[i]); | |
| 546 | |
| 547 if (!string) | |
| 548 continue; | |
| 549 | |
| 550 NPVariant args[1]; | |
| 551 STRINGZ_TO_NPVARIANT(string, args[0]); | |
| 552 NPVariant browserResult; | |
| 553 browser->invoke(obj->npp, outArray, pushIdentifier, args, 1, &br
owserResult); | |
| 554 browser->releasevariantvalue(&browserResult); | |
| 555 browser->memfree(string); | |
| 556 } | |
| 557 | |
| 558 browser->memfree(identifiers); | |
| 559 } | |
| 560 | |
| 561 VOID_TO_NPVARIANT(*result); | |
| 562 return true; | |
| 563 } | |
| 564 return false; | |
| 565 } | |
| 566 | |
| 567 static bool testGetIntIdentifier(PluginObject*, const NPVariant* args, uint32_t
argCount, NPVariant* result) | |
| 568 { | |
| 569 if (argCount != 1) | |
| 570 return false; | |
| 571 | |
| 572 NPIdentifier identifier; | |
| 573 | |
| 574 if (NPVARIANT_IS_DOUBLE(args[0])) { | |
| 575 identifier = browser->getintidentifier((int)NPVARIANT_TO_DOUBLE(args[0])
); | |
| 576 } else if (NPVARIANT_IS_INT32(args[0])) { | |
| 577 identifier = browser->getintidentifier((int)NPVARIANT_TO_INT32(args[0]))
; | |
| 578 } else { | |
| 579 return false; | |
| 580 } | |
| 581 | |
| 582 INT32_TO_NPVARIANT(static_cast<int32_t>(reinterpret_cast<intptr_t>(identifie
r)), *result); | |
| 583 return true; | |
| 584 } | |
| 585 | |
| 586 static bool testGetProperty(PluginObject* obj, const NPVariant* args, uint32_t a
rgCount, NPVariant* result) | |
| 587 { | |
| 588 if (argCount == 0) | |
| 589 return false; | |
| 590 | |
| 591 NPObject *object; | |
| 592 browser->getvalue(obj->npp, NPNVWindowNPObject, &object); | |
| 593 | |
| 594 for (uint32_t i = 0; i < argCount; i++) { | |
| 595 assert(NPVARIANT_IS_STRING(args[i])); | |
| 596 NPUTF8* propertyString = createCStringFromNPVariant(&args[i]); | |
| 597 NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyS
tring); | |
| 598 free(propertyString); | |
| 599 | |
| 600 NPVariant variant; | |
| 601 bool retval = browser->getproperty(obj->npp, object, propertyIdentifier,
&variant); | |
| 602 browser->releaseobject(object); | |
| 603 | |
| 604 if (!retval) | |
| 605 break; | |
| 606 | |
| 607 if (i + 1 < argCount) { | |
| 608 assert(NPVARIANT_IS_OBJECT(variant)); | |
| 609 object = NPVARIANT_TO_OBJECT(variant); | |
| 610 } else { | |
| 611 *result = variant; | |
| 612 return true; | |
| 613 } | |
| 614 } | |
| 615 | |
| 616 VOID_TO_NPVARIANT(*result); | |
| 617 return false; | |
| 618 } | |
| 619 | |
| 620 static bool testEvaluate(PluginObject* obj, const NPVariant* args, uint32_t argC
ount, NPVariant* result) | |
| 621 { | |
| 622 if (argCount != 1 || !NPVARIANT_IS_STRING(args[0])) | |
| 623 return false; | |
| 624 NPObject* windowScriptObject; | |
| 625 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject); | |
| 626 | |
| 627 NPString s = NPVARIANT_TO_STRING(args[0]); | |
| 628 | |
| 629 bool retval = browser->evaluate(obj->npp, windowScriptObject, &s, result); | |
| 630 browser->releaseobject(windowScriptObject); | |
| 631 return retval; | |
| 632 } | |
| 633 | |
| 634 static bool testGetPropertyReturnValue(PluginObject* obj, const NPVariant* args,
uint32_t argCount, NPVariant* result) | |
| 635 { | |
| 636 if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) || !NPVARIANT_IS_STRING(a
rgs[1])) | |
| 637 return false; | |
| 638 | |
| 639 NPUTF8* propertyString = createCStringFromNPVariant(&args[1]); | |
| 640 NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyStrin
g); | |
| 641 free(propertyString); | |
| 642 | |
| 643 NPVariant variant; | |
| 644 bool retval = browser->getproperty(obj->npp, NPVARIANT_TO_OBJECT(args[0]), p
ropertyIdentifier, &variant); | |
| 645 if (retval) | |
| 646 browser->releasevariantvalue(&variant); | |
| 647 | |
| 648 BOOLEAN_TO_NPVARIANT(retval, *result); | |
| 649 return true; | |
| 650 } | |
| 651 | |
| 652 static char* toCString(const NPString& string) | |
| 653 { | |
| 654 char* result = static_cast<char*>(malloc(string.UTF8Length + 1)); | |
| 655 memcpy(result, string.UTF8Characters, string.UTF8Length); | |
| 656 result[string.UTF8Length] = '\0'; | |
| 657 | |
| 658 return result; | |
| 659 } | |
| 660 | |
| 661 static bool testPostURLFile(PluginObject* obj, const NPVariant* args, uint32_t a
rgCount, NPVariant* result) | |
| 662 { | |
| 663 if (argCount != 4 || !NPVARIANT_IS_STRING(args[0]) || !NPVARIANT_IS_STRING(a
rgs[1]) || !NPVARIANT_IS_STRING(args[2]) || !NPVARIANT_IS_STRING(args[3])) | |
| 664 return false; | |
| 665 | |
| 666 NPString urlString = NPVARIANT_TO_STRING(args[0]); | |
| 667 char* url = toCString(urlString); | |
| 668 | |
| 669 NPString targetString = NPVARIANT_TO_STRING(args[1]); | |
| 670 char* target = toCString(targetString); | |
| 671 | |
| 672 NPString pathString = NPVARIANT_TO_STRING(args[2]); | |
| 673 char* path = toCString(pathString); | |
| 674 | |
| 675 NPString contentsString = NPVARIANT_TO_STRING(args[3]); | |
| 676 | |
| 677 FILE* tempFile = fopen(path, "w"); | |
| 678 if (!tempFile) | |
| 679 return false; | |
| 680 | |
| 681 int written = fwrite(contentsString.UTF8Characters, contentsString.UTF8Lengt
h, 1, tempFile); | |
| 682 fclose(tempFile); | |
| 683 if (written != 1) | |
| 684 return false; | |
| 685 | |
| 686 NPError error = browser->posturl(obj->npp, url, target, pathString.UTF8Lengt
h, path, true); | |
| 687 | |
| 688 free(path); | |
| 689 free(target); | |
| 690 free(url); | |
| 691 | |
| 692 BOOLEAN_TO_NPVARIANT(error == NPERR_NO_ERROR, *result); | |
| 693 return true; | |
| 694 } | |
| 695 | |
| 696 static bool testConstruct(PluginObject* obj, const NPVariant* args, uint32_t arg
Count, NPVariant* result) | |
| 697 { | |
| 698 if (!argCount || !NPVARIANT_IS_OBJECT(args[0])) | |
| 699 return false; | |
| 700 | |
| 701 return browser->construct(obj->npp, NPVARIANT_TO_OBJECT(args[0]), args + 1,
argCount - 1, result); | |
| 702 } | |
| 703 | |
| 704 // Helper function to notify the layout test controller that the test completed. | |
| 705 void notifyTestCompletion(NPP npp, NPObject* object) | |
| 706 { | |
| 707 NPVariant result; | |
| 708 NPString script; | |
| 709 script.UTF8Characters = "javascript:window.layoutTestController.notifyDone()
;"; | |
| 710 script.UTF8Length = strlen("javascript:window.layoutTestController.notifyDon
e();"); | |
| 711 browser->evaluate(npp, object, &script, &result); | |
| 712 browser->releasevariantvalue(&result); | |
| 713 } | |
| 714 | |
| 715 bool testDocumentOpen(NPP npp) | |
| 716 { | |
| 717 NPIdentifier documentId = browser->getstringidentifier("document"); | |
| 718 NPIdentifier openId = browser->getstringidentifier("open"); | |
| 719 | |
| 720 NPObject *windowObject = NULL; | |
| 721 browser->getvalue(npp, NPNVWindowNPObject, &windowObject); | |
| 722 if (!windowObject) | |
| 723 return false; | |
| 724 | |
| 725 NPVariant docVariant; | |
| 726 browser->getproperty(npp, windowObject, documentId, &docVariant); | |
| 727 if (docVariant.type != NPVariantType_Object) | |
| 728 return false; | |
| 729 | |
| 730 NPObject *documentObject = NPVARIANT_TO_OBJECT(docVariant); | |
| 731 | |
| 732 NPVariant openArgs[2]; | |
| 733 STRINGZ_TO_NPVARIANT("text/html", openArgs[0]); | |
| 734 STRINGZ_TO_NPVARIANT("_blank", openArgs[1]); | |
| 735 | |
| 736 NPVariant result; | |
| 737 browser->invoke(npp, documentObject, openId, openArgs, 2, &result); | |
| 738 browser->releaseobject(documentObject); | |
| 739 | |
| 740 if (result.type == NPVariantType_Object) { | |
| 741 logWithWindowObjectVariableArgs(windowObject, npp, "DOCUMENT OPEN SUCCES
S"); | |
| 742 notifyTestCompletion(npp, result.value.objectValue); | |
| 743 browser->releaseobject(result.value.objectValue); | |
| 744 return true; | |
| 745 } | |
| 746 | |
| 747 return false; | |
| 748 } | |
| 749 | |
| 750 bool testWindowOpen(NPP npp) | |
| 751 { | |
| 752 NPIdentifier openId = browser->getstringidentifier("open"); | |
| 753 | |
| 754 NPObject *windowObject = NULL; | |
| 755 browser->getvalue(npp, NPNVWindowNPObject, &windowObject); | |
| 756 if (!windowObject) | |
| 757 return false; | |
| 758 | |
| 759 NPVariant openArgs[2]; | |
| 760 STRINGZ_TO_NPVARIANT("about:blank", openArgs[0]); | |
| 761 STRINGZ_TO_NPVARIANT("_blank", openArgs[1]); | |
| 762 | |
| 763 NPVariant result; | |
| 764 browser->invoke(npp, windowObject, openId, openArgs, 2, &result); | |
| 765 if (result.type == NPVariantType_Object) { | |
| 766 logWithWindowObjectVariableArgs(windowObject, npp, "WINDOW OPEN SUCCESS"
); | |
| 767 notifyTestCompletion(npp, result.value.objectValue); | |
| 768 browser->releaseobject(result.value.objectValue); | |
| 769 return true; | |
| 770 } | |
| 771 return false; | |
| 772 } | |
| 773 | |
| 774 static bool pluginInvoke(NPObject* header, NPIdentifier name, const NPVariant* a
rgs, uint32_t argCount, NPVariant* result) | |
| 775 { | |
| 776 PluginObject* plugin = reinterpret_cast<PluginObject*>(header); | |
| 777 if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD]) | |
| 778 return testCallback(plugin, args, argCount, result); | |
| 779 else if (name == pluginMethodIdentifiers[ID_TEST_GETURL]) | |
| 780 return getURL(plugin, args, argCount, result); | |
| 781 else if (name == pluginMethodIdentifiers[ID_REMOVE_DEFAULT_METHOD]) | |
| 782 return removeDefaultMethod(plugin, args, argCount, result); | |
| 783 else if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS]) | |
| 784 return testDOMAccess(plugin, args, argCount, result); | |
| 785 else if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY]) | |
| 786 return getURLNotify(plugin, args, argCount, result); | |
| 787 else if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT]) | |
| 788 return testInvokeDefault(plugin, args, argCount, result); | |
| 789 else if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE]) | |
| 790 return testEnumerate(plugin, args, argCount, result); | |
| 791 else if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM]) | |
| 792 return destroyStream(plugin, args, argCount, result); | |
| 793 else if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER]) | |
| 794 return testGetIntIdentifier(plugin, args, argCount, result); | |
| 795 else if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE]) | |
| 796 return testEvaluate(plugin, args, argCount, result); | |
| 797 else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY]) | |
| 798 return testGetProperty(plugin, args, argCount, result); | |
| 799 else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY_RETURN_VALUE]) | |
| 800 return testGetPropertyReturnValue(plugin, args, argCount, result); | |
| 801 else if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_STRING]) | |
| 802 return testIdentifierToString(plugin, args, argCount, result); | |
| 803 else if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_INT]) | |
| 804 return testIdentifierToInt(plugin, args, argCount, result); | |
| 805 else if (name == pluginMethodIdentifiers[ID_TEST_POSTURL_FILE]) | |
| 806 return testPostURLFile(plugin, args, argCount, result); | |
| 807 else if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD_RET] || | |
| 808 name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD_RETURN]) { | |
| 809 // call whatever method name we're given, and pass it the 'window' obj. | |
| 810 // we expect the function to return its argument. | |
| 811 if (argCount > 0 && NPVARIANT_IS_STRING(args[0])) { | |
| 812 NPObject *windowScriptObject; | |
| 813 browser->getvalue(plugin->npp, NPNVWindowNPObject, &windowScriptObje
ct); | |
| 814 | |
| 815 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]); | |
| 816 NPIdentifier callbackIdentifier = browser->getstringidentifier(callb
ackString); | |
| 817 free(callbackString); | |
| 818 | |
| 819 NPVariant callbackArgs[1]; | |
| 820 OBJECT_TO_NPVARIANT(windowScriptObject, callbackArgs[0]); | |
| 821 | |
| 822 NPVariant browserResult; | |
| 823 browser->invoke(plugin->npp, windowScriptObject, callbackIdentifier, | |
| 824 callbackArgs, 1, &browserResult); | |
| 825 | |
| 826 if (NPVARIANT_IS_OBJECT(browserResult)) { | |
| 827 // Now return the callbacks return value back to our caller. | |
| 828 // BUG 897451: This should be the same as the | |
| 829 // windowScriptObject, but its not (in Chrome) - or at least, it | |
| 830 // has a different refcount. This means Chrome will delete the | |
| 831 // object before returning it and the calling JS gets a garbage | |
| 832 // value. Firefox handles it fine. | |
| 833 OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(browserResult), *result)
; | |
| 834 } else { | |
| 835 browser->releasevariantvalue(&browserResult); | |
| 836 VOID_TO_NPVARIANT(*result); | |
| 837 } | |
| 838 | |
| 839 return true; | |
| 840 } | |
| 841 } else if (name == pluginMethodIdentifiers[ID_TEST_CREATE_TEST_OBJECT]) { | |
| 842 NPObject *testObject = browser->createobject(plugin->npp, getTestClass()
); | |
| 843 assert(testObject->referenceCount == 1); | |
| 844 OBJECT_TO_NPVARIANT(testObject, *result); | |
| 845 return true; | |
| 846 } else if (name == pluginMethodIdentifiers[ID_TEST_PASS_TEST_OBJECT]) { | |
| 847 // call whatever method name we're given, and pass it our second | |
| 848 // argument. | |
| 849 if (argCount > 1 && NPVARIANT_IS_STRING(args[0])) { | |
| 850 NPObject *windowScriptObject; | |
| 851 browser->getvalue(plugin->npp, NPNVWindowNPObject, &windowScriptObje
ct); | |
| 852 | |
| 853 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]); | |
| 854 NPIdentifier callbackIdentifier = browser->getstringidentifier(callb
ackString); | |
| 855 free(callbackString); | |
| 856 | |
| 857 NPVariant browserResult; | |
| 858 browser->invoke(plugin->npp, windowScriptObject, callbackIdentifier,
&args[1], 1, &browserResult); | |
| 859 browser->releasevariantvalue(&browserResult); | |
| 860 | |
| 861 VOID_TO_NPVARIANT(*result); | |
| 862 return true; | |
| 863 } | |
| 864 } else if (name == pluginMethodIdentifiers[ID_TEST_CLONE_OBJECT]) { | |
| 865 // Create another instance of the same class | |
| 866 NPObject *new_object = browser->createobject(plugin->npp, &pluginClass); | |
| 867 assert(new_object->referenceCount == 1); | |
| 868 OBJECT_TO_NPVARIANT(new_object, *result); | |
| 869 return true; | |
| 870 } else if (name == pluginMethodIdentifiers[ID_TEST_SCRIPT_OBJECT_INVOKE]) { | |
| 871 if (argCount > 1 && NPVARIANT_IS_STRING(args[0])) { | |
| 872 // Invoke a script callback to get a script NPObject. Then call | |
| 873 // a method on the script NPObject passing it a freshly created | |
| 874 // NPObject. | |
| 875 // Arguments: | |
| 876 // arg1: Callback that returns a script object. | |
| 877 // arg2: Name of the method to call on the script object returned | |
| 878 // from the callback | |
| 879 NPObject *windowScriptObject; | |
| 880 browser->getvalue(plugin->npp, NPNVWindowNPObject, | |
| 881 &windowScriptObject); | |
| 882 | |
| 883 // Arg1 is the name of the callback | |
| 884 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]); | |
| 885 NPIdentifier callbackIdentifier = | |
| 886 browser->getstringidentifier(callbackString); | |
| 887 free(callbackString); | |
| 888 | |
| 889 // Invoke a callback that returns a script object | |
| 890 NPVariant object_result; | |
| 891 browser->invoke(plugin->npp, windowScriptObject, callbackIdentifier, | |
| 892 &args[1], 1, &object_result); | |
| 893 | |
| 894 // Script object returned | |
| 895 NPObject *script_object = object_result.value.objectValue; | |
| 896 | |
| 897 // Arg2 is the name of the method to be called on the script object | |
| 898 NPUTF8* object_mehod_string = createCStringFromNPVariant(&args[1]); | |
| 899 NPIdentifier object_method = | |
| 900 browser->getstringidentifier(object_mehod_string); | |
| 901 free(object_mehod_string); | |
| 902 | |
| 903 // Create a fresh NPObject to be passed as an argument | |
| 904 NPObject *object_arg = browser->createobject(plugin->npp, &pluginCla
ss); | |
| 905 NPVariant invoke_args[1]; | |
| 906 OBJECT_TO_NPVARIANT(object_arg, invoke_args[0]); | |
| 907 | |
| 908 // Invoke the script method | |
| 909 NPVariant object_method_result; | |
| 910 browser->invoke(plugin->npp, script_object, object_method, | |
| 911 invoke_args, 1, &object_method_result); | |
| 912 | |
| 913 browser->releasevariantvalue(&object_result); | |
| 914 VOID_TO_NPVARIANT(*result); | |
| 915 if (NPVARIANT_IS_OBJECT(object_method_result)) { | |
| 916 // Now return the callbacks return value back to our caller. | |
| 917 // BUG 897451: This should be the same as the | |
| 918 // windowScriptObject, but its not (in Chrome) - or at least, it | |
| 919 // has a different refcount. This means Chrome will delete the | |
| 920 // object before returning it and the calling JS gets a garbage | |
| 921 // value. Firefox handles it fine. | |
| 922 OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(object_method_result), | |
| 923 *result); | |
| 924 } else { | |
| 925 browser->releasevariantvalue(&object_method_result); | |
| 926 VOID_TO_NPVARIANT(*result); | |
| 927 } | |
| 928 return true; | |
| 929 } | |
| 930 } else if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_AND_GET_VALUE]) | |
| 931 return testCallbackAndGetValue(plugin, args, argCount, result); | |
| 932 else if (name == pluginMethodIdentifiers[ID_TEST_CONSTRUCT]) | |
| 933 return testConstruct(plugin, args, argCount, result); | |
| 934 else if (name == pluginMethodIdentifiers[ID_DESTROY_NULL_STREAM]) | |
| 935 return destroyNullStream(plugin, args, argCount, result); | |
| 936 else if (name == pluginMethodIdentifiers[ID_TEST_HAS_PROPERTY]) | |
| 937 return testHasProperty(plugin, args, argCount, result); | |
| 938 else if (name == pluginMethodIdentifiers[ID_TEST_HAS_METHOD]) | |
| 939 return testHasMethod(plugin, args, argCount, result); | |
| 940 else if (name == pluginMethodIdentifiers[ID_TEST_THROW_EXCEPTION_METHOD]) { | |
| 941 browser->setexception(header, "plugin object testThrowException SUCCESS"
); | |
| 942 return true; | |
| 943 } else if (name == pluginMethodIdentifiers[ID_TEST_GET_BROWSER_PROPERTY]) { | |
| 944 browser->getproperty(plugin->npp, NPVARIANT_TO_OBJECT(args[0]), stringVa
riantToIdentifier(args[1]), result); | |
| 945 return true; | |
| 946 } else if (name == pluginMethodIdentifiers[ID_TEST_SET_BROWSER_PROPERTY]) { | |
| 947 browser->setproperty(plugin->npp, NPVARIANT_TO_OBJECT(args[0]), stringVa
riantToIdentifier(args[1]), &args[2]); | |
| 948 return true; | |
| 949 }// else if (name == pluginMethodIdentifiers[ID_TEST_FAIL_METHOD]) | |
| 950 // return browser->invoke(plugin->npp, 0, name, args, argCount, result); | |
| 951 | |
| 952 return false; | |
| 953 } | |
| 954 | |
| 955 static bool pluginInvokeDefault(NPObject* obj, const NPVariant* args, uint32_t a
rgCount, NPVariant* result) | |
| 956 { | |
| 957 INT32_TO_NPVARIANT(1, *result); | |
| 958 return true; | |
| 959 } | |
| 960 | |
| 961 static void pluginInvalidate(NPObject* obj) | |
| 962 { | |
| 963 } | |
| 964 | |
| 965 static NPObject *pluginAllocate(NPP npp, NPClass *theClass) | |
| 966 { | |
| 967 PluginObject* newInstance = (PluginObject*)malloc(sizeof(PluginObject)); | |
| 968 | |
| 969 if (!identifiersInitialized) { | |
| 970 identifiersInitialized = true; | |
| 971 initializeIdentifiers(); | |
| 972 } | |
| 973 | |
| 974 newInstance->npp = npp; | |
| 975 newInstance->testObject = browser->createobject(npp, getTestClass()); | |
| 976 newInstance->eventLogging = false; | |
| 977 newInstance->onStreamLoad = 0; | |
| 978 newInstance->onStreamDestroy = 0; | |
| 979 newInstance->onURLNotify = 0; | |
| 980 newInstance->logDestroy = false; | |
| 981 newInstance->logSetWindow = false; | |
| 982 newInstance->returnErrorFromNewStream = false; | |
| 983 newInstance->stream = 0; | |
| 984 | |
| 985 newInstance->firstUrl = NULL; | |
| 986 newInstance->firstHeaders = NULL; | |
| 987 newInstance->lastUrl = NULL; | |
| 988 newInstance->lastHeaders = NULL; | |
| 989 | |
| 990 newInstance->testDocumentOpenInDestroyStream = false; | |
| 991 newInstance->testWindowOpen = false; | |
| 992 newInstance->testKeyboardFocusForPlugins = false; | |
| 993 | |
| 994 newInstance->evaluateScriptOnMouseDownOrKeyDown = NULL; | |
| 995 newInstance->mouseDownForEvaluateScript = false; | |
| 996 | |
| 997 return (NPObject*)newInstance; | |
| 998 } | |
| 999 | |
| 1000 static void pluginDeallocate(NPObject* header) | |
| 1001 { | |
| 1002 PluginObject* plugin = reinterpret_cast<PluginObject*>(header); | |
| 1003 browser->releaseobject(plugin->testObject); | |
| 1004 | |
| 1005 free(plugin->firstUrl); | |
| 1006 free(plugin->firstHeaders); | |
| 1007 free(plugin->lastUrl); | |
| 1008 free(plugin->lastHeaders); | |
| 1009 free(plugin); | |
| 1010 } | |
| 1011 | |
| 1012 void handleCallback(PluginObject* object, const char *url, NPReason reason, void
*notifyData) | |
| 1013 { | |
| 1014 assert(object); | |
| 1015 | |
| 1016 NPVariant args[2]; | |
| 1017 | |
| 1018 NPObject *windowScriptObject; | |
| 1019 browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject); | |
| 1020 | |
| 1021 NPIdentifier callbackIdentifier = notifyData; | |
| 1022 | |
| 1023 INT32_TO_NPVARIANT(reason, args[0]); | |
| 1024 | |
| 1025 char *strHdr = NULL; | |
| 1026 if (object->firstUrl && object->firstHeaders && object->lastUrl && object->l
astHeaders) { | |
| 1027 // Format expected by JavaScript validator: four fields separated by \n\
n: | |
| 1028 // First URL; first header block; last URL; last header block. | |
| 1029 // Note that header blocks already end with \n due to how NPStream::head
ers works. | |
| 1030 int len = strlen(object->firstUrl) + 2 | |
| 1031 + strlen(object->firstHeaders) + 1 | |
| 1032 + strlen(object->lastUrl) + 2 | |
| 1033 + strlen(object->lastHeaders) + 1; | |
| 1034 strHdr = (char*)malloc(len + 1); | |
| 1035 snprintf(strHdr, len + 1, "%s\n\n%s\n%s\n\n%s\n", | |
| 1036 object->firstUrl, object->firstHeaders, object->lastUrl, object
->lastHeaders); | |
| 1037 STRINGN_TO_NPVARIANT(strHdr, len, args[1]); | |
| 1038 } else | |
| 1039 NULL_TO_NPVARIANT(args[1]); | |
| 1040 | |
| 1041 NPVariant browserResult; | |
| 1042 browser->invoke(object->npp, windowScriptObject, callbackIdentifier, args, 2
, &browserResult); | |
| 1043 browser->releasevariantvalue(&browserResult); | |
| 1044 | |
| 1045 free(strHdr); | |
| 1046 } | |
| 1047 | |
| 1048 void notifyStream(PluginObject* object, const char *url, const char *headers) | |
| 1049 { | |
| 1050 if (object->firstUrl == NULL) { | |
| 1051 if (url) | |
| 1052 object->firstUrl = strdup(url); | |
| 1053 if (headers) | |
| 1054 object->firstHeaders = strdup(headers); | |
| 1055 } else { | |
| 1056 free(object->lastUrl); | |
| 1057 free(object->lastHeaders); | |
| 1058 object->lastUrl = (url ? strdup(url) : NULL); | |
| 1059 object->lastHeaders = (headers ? strdup(headers) : NULL); | |
| 1060 } | |
| 1061 } | |
| 1062 | |
| 1063 void testNPRuntime(NPP npp) | |
| 1064 { | |
| 1065 NPObject* windowScriptObject; | |
| 1066 browser->getvalue(npp, NPNVWindowNPObject, &windowScriptObject); | |
| 1067 | |
| 1068 // Invoke | |
| 1069 NPIdentifier testNPInvoke = browser->getstringidentifier("testNPInvoke"); | |
| 1070 NPVariant args[7]; | |
| 1071 | |
| 1072 VOID_TO_NPVARIANT(args[0]); | |
| 1073 NULL_TO_NPVARIANT(args[1]); | |
| 1074 BOOLEAN_TO_NPVARIANT(true, args[2]); | |
| 1075 INT32_TO_NPVARIANT(242, args[3]); | |
| 1076 DOUBLE_TO_NPVARIANT(242.242, args[4]); | |
| 1077 STRINGZ_TO_NPVARIANT("Hello, World", args[5]); | |
| 1078 OBJECT_TO_NPVARIANT(windowScriptObject, args[6]); | |
| 1079 | |
| 1080 NPVariant result; | |
| 1081 if (browser->invoke(npp, windowScriptObject, testNPInvoke, args, 7, &result)
) | |
| 1082 browser->releasevariantvalue(&result); | |
| 1083 | |
| 1084 browser->releaseobject(windowScriptObject); | |
| 1085 } | |
| OLD | NEW |