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