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