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