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