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