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