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