1 : /* ***** BEGIN LICENSE BLOCK *****
2 : *
3 : * Copyright (c) 2008, Mozilla Corporation
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are met:
8 : *
9 : * * Redistributions of source code must retain the above copyright notice, this
10 : * list of conditions and the following disclaimer.
11 : * * Redistributions in binary form must reproduce the above copyright notice,
12 : * this list of conditions and the following disclaimer in the documentation
13 : * and/or other materials provided with the distribution.
14 : * * Neither the name of the Mozilla Corporation nor the names of its
15 : * contributors may be used to endorse or promote products derived from this
16 : * software without specific prior written permission.
17 : *
18 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 : * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 : * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
22 : * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 : * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 : * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 : * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 : *
29 : * Contributor(s):
30 : * Dave Townsend <dtownsend@oxymoronical.com>
31 : * Josh Aas <josh@mozilla.com>
32 : *
33 : * ***** END LICENSE BLOCK ***** */
34 :
35 : #include "nptest.h"
36 : #include "nptest_utils.h"
37 : #include "nptest_platform.h"
38 :
39 : #include "mozilla/IntentionalCrash.h"
40 :
41 : #include <stdlib.h>
42 : #include <string.h>
43 : #include <stdio.h>
44 : #include <iostream>
45 : #include <string>
46 : #include <sstream>
47 : #include <list>
48 :
49 : #ifdef XP_WIN
50 : #include <process.h>
51 : #include <float.h>
52 : #include <windows.h>
53 : #define getpid _getpid
54 : #else
55 : #include <unistd.h>
56 : #include <pthread.h>
57 : #endif
58 :
59 : using namespace std;
60 :
61 : #define PLUGIN_NAME "Test Plug-in"
62 : #define PLUGIN_DESCRIPTION "Plug-in for testing purposes.\xE2\x84\xA2 " \
63 : "(\xe0\xa4\xb9\xe0\xa4\xbf\xe0\xa4\xa8\xe0\xa5\x8d\xe0\xa4\xa6\xe0\xa5\x80 " \
64 : "\xe4\xb8\xad\xe6\x96\x87 " \
65 : "\xd8\xa7\xd9\x84\xd8\xb9\xd8\xb1\xd8\xa8\xd9\x8a\xd8\xa9)"
66 : #define PLUGIN_VERSION "1.0.0.0"
67 :
68 : #define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
69 : #define STATIC_ASSERT(condition) \
70 : extern void np_static_assert(int arg[(condition) ? 1 : -1])
71 :
72 : static char sPluginName[] = PLUGIN_NAME;
73 : static char sPluginDescription[] = PLUGIN_DESCRIPTION;
74 : static char sPluginVersion[] = PLUGIN_VERSION;
75 :
76 : //
77 : // Intentional crash
78 : //
79 :
80 : int gCrashCount = 0;
81 :
82 0 : static void Crash()
83 : {
84 0 : int *pi = NULL;
85 0 : *pi = 55; // Crash dereferencing null pointer
86 0 : ++gCrashCount;
87 0 : }
88 :
89 : static void
90 0 : IntentionalCrash()
91 : {
92 0 : mozilla::NoteIntentionalCrash("plugin");
93 0 : Crash();
94 0 : }
95 :
96 : //
97 : // static data
98 : //
99 :
100 : static NPNetscapeFuncs* sBrowserFuncs = NULL;
101 : static NPClass sNPClass;
102 :
103 : void
104 : asyncCallback(void* cookie);
105 :
106 : //
107 : // identifiers
108 : //
109 :
110 : typedef bool (* ScriptableFunction)
111 : (NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
112 :
113 : static bool npnEvaluateTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
114 : static bool npnInvokeTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
115 : static bool npnInvokeDefaultTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
116 : static bool setUndefinedValueTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
117 : static bool identifierToStringTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
118 : static bool timerTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
119 : static bool queryPrivateModeState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
120 : static bool lastReportedPrivateModeState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
121 : static bool hasWidget(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
122 : static bool getEdge(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
123 : static bool getClipRegionRectCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
124 : static bool getClipRegionRectEdge(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
125 : static bool startWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
126 : static bool getInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
127 : static bool stopWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
128 : static bool getLastMouseX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
129 : static bool getLastMouseY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
130 : static bool getPaintCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
131 : static bool getWidthAtLastPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
132 : static bool setInvalidateDuringPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
133 : static bool getError(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
134 : static bool doInternalConsistencyCheck(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
135 : static bool setColor(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
136 : static bool throwExceptionNextInvoke(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
137 : static bool convertPointX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
138 : static bool convertPointY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
139 : static bool streamTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
140 : static bool setPluginWantsAllStreams(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
141 : static bool crashPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
142 : static bool crashOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
143 : static bool getObjectValue(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
144 : static bool checkObjectValue(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
145 : static bool enableFPExceptions(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
146 : static bool setCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
147 : static bool getCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
148 : static bool getAuthInfo(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
149 : static bool asyncCallbackTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
150 : static bool checkGCRace(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
151 : static bool hangPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
152 : static bool getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
153 : static bool callOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
154 : static bool reinitWidget(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
155 : static bool crashPluginInNestedLoop(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
156 : static bool destroySharedGfxStuff(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
157 : static bool propertyAndMethod(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
158 : static bool getTopLevelWindowActivationState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
159 : static bool getTopLevelWindowActivationEventCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
160 : static bool getFocusState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
161 : static bool getFocusEventCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
162 : static bool getEventModel(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
163 : static bool getReflector(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
164 : static bool isVisible(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
165 : static bool getWindowPosition(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
166 : static bool constructObject(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
167 : static bool setSitesWithData(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
168 : static bool setSitesWithDataCapabilities(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
169 : static bool getLastKeyText(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
170 : static bool getNPNVdocumentOrigin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
171 :
172 : static const NPUTF8* sPluginMethodIdentifierNames[] = {
173 : "npnEvaluateTest",
174 : "npnInvokeTest",
175 : "npnInvokeDefaultTest",
176 : "setUndefinedValueTest",
177 : "identifierToStringTest",
178 : "timerTest",
179 : "queryPrivateModeState",
180 : "lastReportedPrivateModeState",
181 : "hasWidget",
182 : "getEdge",
183 : "getClipRegionRectCount",
184 : "getClipRegionRectEdge",
185 : "startWatchingInstanceCount",
186 : "getInstanceCount",
187 : "stopWatchingInstanceCount",
188 : "getLastMouseX",
189 : "getLastMouseY",
190 : "getPaintCount",
191 : "getWidthAtLastPaint",
192 : "setInvalidateDuringPaint",
193 : "getError",
194 : "doInternalConsistencyCheck",
195 : "setColor",
196 : "throwExceptionNextInvoke",
197 : "convertPointX",
198 : "convertPointY",
199 : "streamTest",
200 : "setPluginWantsAllStreams",
201 : "crash",
202 : "crashOnDestroy",
203 : "getObjectValue",
204 : "checkObjectValue",
205 : "enableFPExceptions",
206 : "setCookie",
207 : "getCookie",
208 : "getAuthInfo",
209 : "asyncCallbackTest",
210 : "checkGCRace",
211 : "hang",
212 : "getClipboardText",
213 : "callOnDestroy",
214 : "reinitWidget",
215 : "crashInNestedLoop",
216 : "destroySharedGfxStuff",
217 : "propertyAndMethod",
218 : "getTopLevelWindowActivationState",
219 : "getTopLevelWindowActivationEventCount",
220 : "getFocusState",
221 : "getFocusEventCount",
222 : "getEventModel",
223 : "getReflector",
224 : "isVisible",
225 : "getWindowPosition",
226 : "constructObject",
227 : "setSitesWithData",
228 : "setSitesWithDataCapabilities",
229 : "getLastKeyText",
230 : "getNPNVdocumentOrigin"
231 : };
232 : static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
233 : static const ScriptableFunction sPluginMethodFunctions[] = {
234 : npnEvaluateTest,
235 : npnInvokeTest,
236 : npnInvokeDefaultTest,
237 : setUndefinedValueTest,
238 : identifierToStringTest,
239 : timerTest,
240 : queryPrivateModeState,
241 : lastReportedPrivateModeState,
242 : hasWidget,
243 : getEdge,
244 : getClipRegionRectCount,
245 : getClipRegionRectEdge,
246 : startWatchingInstanceCount,
247 : getInstanceCount,
248 : stopWatchingInstanceCount,
249 : getLastMouseX,
250 : getLastMouseY,
251 : getPaintCount,
252 : getWidthAtLastPaint,
253 : setInvalidateDuringPaint,
254 : getError,
255 : doInternalConsistencyCheck,
256 : setColor,
257 : throwExceptionNextInvoke,
258 : convertPointX,
259 : convertPointY,
260 : streamTest,
261 : setPluginWantsAllStreams,
262 : crashPlugin,
263 : crashOnDestroy,
264 : getObjectValue,
265 : checkObjectValue,
266 : enableFPExceptions,
267 : setCookie,
268 : getCookie,
269 : getAuthInfo,
270 : asyncCallbackTest,
271 : checkGCRace,
272 : hangPlugin,
273 : getClipboardText,
274 : callOnDestroy,
275 : reinitWidget,
276 : crashPluginInNestedLoop,
277 : destroySharedGfxStuff,
278 : propertyAndMethod,
279 : getTopLevelWindowActivationState,
280 : getTopLevelWindowActivationEventCount,
281 : getFocusState,
282 : getFocusEventCount,
283 : getEventModel,
284 : getReflector,
285 : isVisible,
286 : getWindowPosition,
287 : constructObject,
288 : setSitesWithData,
289 : setSitesWithDataCapabilities,
290 : getLastKeyText,
291 : getNPNVdocumentOrigin
292 : };
293 :
294 : STATIC_ASSERT(ARRAY_LENGTH(sPluginMethodIdentifierNames) ==
295 : ARRAY_LENGTH(sPluginMethodFunctions));
296 :
297 : static const NPUTF8* sPluginPropertyIdentifierNames[] = {
298 : "propertyAndMethod"
299 : };
300 : static NPIdentifier sPluginPropertyIdentifiers[ARRAY_LENGTH(sPluginPropertyIdentifierNames)];
301 : static NPVariant sPluginPropertyValues[ARRAY_LENGTH(sPluginPropertyIdentifierNames)];
302 :
303 : struct URLNotifyData
304 : {
305 : const char* cookie;
306 : NPObject* writeCallback;
307 : NPObject* notifyCallback;
308 : NPObject* redirectCallback;
309 : bool allowRedirects;
310 : uint32_t size;
311 : char* data;
312 : };
313 :
314 : static URLNotifyData kNotifyData = {
315 : "static-cookie",
316 : NULL,
317 : NULL,
318 : NULL,
319 : false,
320 : 0,
321 : NULL
322 : };
323 :
324 : static const char* SUCCESS_STRING = "pass";
325 :
326 : static bool sIdentifiersInitialized = false;
327 :
328 : struct timerEvent {
329 : int32_t timerIdReceive;
330 : int32_t timerIdSchedule;
331 : uint32_t timerInterval;
332 : bool timerRepeat;
333 : int32_t timerIdUnschedule;
334 : };
335 : static timerEvent timerEvents[] = {
336 : {-1, 0, 200, false, -1},
337 : {0, 0, 400, false, -1},
338 : {0, 0, 200, true, -1},
339 : {0, 1, 400, true, -1},
340 : {0, -1, 0, false, 0},
341 : {1, -1, 0, false, -1},
342 : {1, -1, 0, false, 1},
343 : };
344 : static uint32_t currentTimerEventCount = 0;
345 : static uint32_t totalTimerEvents = sizeof(timerEvents) / sizeof(timerEvent);
346 :
347 : /**
348 : * Incremented for every startWatchingInstanceCount.
349 : */
350 : static int32_t sCurrentInstanceCountWatchGeneration = 0;
351 : /**
352 : * Tracks the number of instances created or destroyed since the last
353 : * startWatchingInstanceCount.
354 : */
355 : static int32_t sInstanceCount = 0;
356 : /**
357 : * True when we've had a startWatchingInstanceCount with no corresponding
358 : * stopWatchingInstanceCount.
359 : */
360 : static bool sWatchingInstanceCount = false;
361 :
362 : /**
363 : * A list representing sites for which the plugin has stored data. See
364 : * NPP_ClearSiteData and NPP_GetSitesWithData.
365 : */
366 0 : struct siteData {
367 : string site;
368 : uint64_t flags;
369 : uint64_t age;
370 : };
371 : static list<siteData>* sSitesWithData;
372 : static bool sClearByAgeSupported;
373 :
374 0 : static void initializeIdentifiers()
375 : {
376 0 : if (!sIdentifiersInitialized) {
377 : NPN_GetStringIdentifiers(sPluginMethodIdentifierNames,
378 0 : ARRAY_LENGTH(sPluginMethodIdentifierNames), sPluginMethodIdentifiers);
379 : NPN_GetStringIdentifiers(sPluginPropertyIdentifierNames,
380 0 : ARRAY_LENGTH(sPluginPropertyIdentifierNames), sPluginPropertyIdentifiers);
381 :
382 0 : sIdentifiersInitialized = true;
383 :
384 : // Check whether NULL is handled in NPN_GetStringIdentifiers
385 : NPIdentifier IDList[2];
386 : static char const *const kIDNames[2] = { NULL, "setCookie" };
387 0 : NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(kIDNames), 2, IDList);
388 : }
389 0 : }
390 :
391 0 : static void clearIdentifiers()
392 : {
393 : memset(sPluginMethodIdentifiers, 0,
394 0 : ARRAY_LENGTH(sPluginMethodIdentifiers) * sizeof(NPIdentifier));
395 : memset(sPluginPropertyIdentifiers, 0,
396 0 : ARRAY_LENGTH(sPluginPropertyIdentifiers) * sizeof(NPIdentifier));
397 :
398 0 : sIdentifiersInitialized = false;
399 0 : }
400 :
401 0 : static void addRange(InstanceData* instanceData, const char* range)
402 : {
403 : char rangestr[16];
404 0 : strncpy(rangestr, range, sizeof(rangestr));
405 0 : const char* str1 = strtok(rangestr, ",");
406 0 : const char* str2 = str1 ? strtok(NULL, ",") : NULL;
407 0 : if (str1 && str2) {
408 0 : TestRange* byterange = new TestRange;
409 0 : byterange->offset = atoi(str1);
410 0 : byterange->length = atoi(str2);
411 0 : byterange->waiting = true;
412 0 : byterange->next = instanceData->testrange;
413 0 : instanceData->testrange = byterange;
414 : }
415 0 : }
416 :
417 0 : static void sendBufferToFrame(NPP instance)
418 : {
419 0 : InstanceData* instanceData = (InstanceData*)(instance->pdata);
420 0 : string outbuf;
421 0 : if (!instanceData->npnNewStream) outbuf = "data:text/html,";
422 0 : const char* buf = reinterpret_cast<char *>(instanceData->streamBuf);
423 0 : int32_t bufsize = instanceData->streamBufSize;
424 0 : if (instanceData->streamMode == NP_ASFILE ||
425 : instanceData->streamMode == NP_ASFILEONLY) {
426 0 : buf = reinterpret_cast<char *>(instanceData->fileBuf);
427 0 : bufsize = instanceData->fileBufSize;
428 : }
429 0 : if (instanceData->err.str().length() > 0) {
430 0 : outbuf.append(instanceData->err.str());
431 : }
432 0 : else if (bufsize > 0) {
433 0 : outbuf.append(buf);
434 : }
435 : else {
436 0 : outbuf.append("Error: no data in buffer");
437 : }
438 :
439 0 : if (instanceData->npnNewStream &&
440 0 : instanceData->err.str().length() == 0) {
441 0 : char typeHTML[] = "text/html";
442 : NPStream* stream;
443 0 : printf("calling NPN_NewStream...");
444 : NPError err = NPN_NewStream(instance, typeHTML,
445 0 : instanceData->frame.c_str(), &stream);
446 0 : printf("return value %d\n", err);
447 0 : if (err != NPERR_NO_ERROR) {
448 0 : instanceData->err << "NPN_NewStream returned " << err;
449 : return;
450 : }
451 :
452 0 : int32_t bytesToWrite = outbuf.length();
453 0 : int32_t bytesWritten = 0;
454 0 : while ((bytesToWrite - bytesWritten) > 0) {
455 : int32_t numBytes = (bytesToWrite - bytesWritten) <
456 : instanceData->streamChunkSize ?
457 0 : bytesToWrite - bytesWritten : instanceData->streamChunkSize;
458 : int32_t written = NPN_Write(instance, stream,
459 0 : numBytes, (void*)(outbuf.c_str() + bytesWritten));
460 0 : if (written <= 0) {
461 0 : instanceData->err << "NPN_Write returned " << written;
462 0 : break;
463 : }
464 0 : bytesWritten += numBytes;
465 0 : printf("%d bytes written, total %d\n", written, bytesWritten);
466 : }
467 0 : err = NPN_DestroyStream(instance, stream, NPRES_DONE);
468 0 : if (err != NPERR_NO_ERROR) {
469 0 : instanceData->err << "NPN_DestroyStream returned " << err;
470 : }
471 : }
472 : else {
473 : // Convert CRLF to LF, and escape most other non-alphanumeric chars.
474 0 : for (size_t i = 0; i < outbuf.length(); i++) {
475 0 : if (outbuf[i] == '\n') {
476 0 : outbuf.replace(i, 1, "%0a");
477 0 : i += 2;
478 : }
479 0 : else if (outbuf[i] == '\r') {
480 0 : outbuf.replace(i, 1, "");
481 0 : i -= 1;
482 : }
483 : else {
484 0 : int ascii = outbuf[i];
485 0 : if (!((ascii >= ',' && ascii <= ';') ||
486 : (ascii >= 'A' && ascii <= 'Z') ||
487 0 : (ascii >= 'a' && ascii <= 'z'))) {
488 : char hex[8];
489 0 : sprintf(hex, "%%%x", ascii);
490 0 : outbuf.replace(i, 1, hex);
491 0 : i += 2;
492 : }
493 : }
494 : }
495 :
496 : NPError err = NPN_GetURL(instance, outbuf.c_str(),
497 0 : instanceData->frame.c_str());
498 0 : if (err != NPERR_NO_ERROR) {
499 0 : instanceData->err << "NPN_GetURL returned " << err;
500 : }
501 : }
502 : }
503 :
504 : TestFunction
505 0 : getFuncFromString(const char* funcname)
506 : {
507 : FunctionTable funcTable[] =
508 : {
509 : { FUNCTION_NPP_NEWSTREAM, "npp_newstream" },
510 : { FUNCTION_NPP_WRITEREADY, "npp_writeready" },
511 : { FUNCTION_NPP_WRITE, "npp_write" },
512 : { FUNCTION_NPP_DESTROYSTREAM, "npp_destroystream" },
513 : { FUNCTION_NPP_WRITE_RPC, "npp_write_rpc" },
514 : { FUNCTION_NONE, NULL }
515 0 : };
516 0 : int32_t i = 0;
517 0 : while(funcTable[i].funcName) {
518 0 : if (!strcmp(funcname, funcTable[i].funcName)) return funcTable[i].funcId;
519 0 : i++;
520 : }
521 0 : return FUNCTION_NONE;
522 : }
523 :
524 : static void
525 0 : DuplicateNPVariant(NPVariant& aDest, const NPVariant& aSrc)
526 : {
527 0 : if (NPVARIANT_IS_STRING(aSrc)) {
528 0 : NPString src = NPVARIANT_TO_STRING(aSrc);
529 0 : char* buf = new char[src.UTF8Length];
530 0 : strncpy(buf, src.UTF8Characters, src.UTF8Length);
531 0 : STRINGN_TO_NPVARIANT(buf, src.UTF8Length, aDest);
532 : }
533 0 : else if (NPVARIANT_IS_OBJECT(aSrc)) {
534 : NPObject* obj =
535 0 : NPN_RetainObject(NPVARIANT_TO_OBJECT(aSrc));
536 0 : OBJECT_TO_NPVARIANT(obj, aDest);
537 : }
538 : else {
539 0 : aDest = aSrc;
540 : }
541 0 : }
542 :
543 : void
544 0 : drawAsyncBitmapColor(InstanceData* instanceData)
545 : {
546 0 : NPP npp = instanceData->npp;
547 :
548 0 : PRUint32 *pixelData = (PRUint32*)instanceData->backBuffer->bitmap.data;
549 :
550 0 : PRUint32 rgba = instanceData->scriptableObject->drawColor;
551 :
552 : unsigned char subpixels[4];
553 0 : subpixels[0] = rgba & 0xFF;
554 0 : subpixels[1] = (rgba & 0xFF00) >> 8;
555 0 : subpixels[2] = (rgba & 0xFF0000) >> 16;
556 0 : subpixels[3] = (rgba & 0xFF000000) >> 24;
557 :
558 0 : subpixels[0] = PRUint8(float(subpixels[3] * subpixels[0]) / 0xFF);
559 0 : subpixels[1] = PRUint8(float(subpixels[3] * subpixels[1]) / 0xFF);
560 0 : subpixels[2] = PRUint8(float(subpixels[3] * subpixels[2]) / 0xFF);
561 : PRUint32 premultiplied;
562 0 : memcpy(&premultiplied, subpixels, sizeof(premultiplied));
563 :
564 0 : for (PRUint32* lastPixel = pixelData + instanceData->backBuffer->size.width * instanceData->backBuffer->size.height;
565 : pixelData < lastPixel;
566 : ++pixelData) {
567 0 : *pixelData = premultiplied;
568 : }
569 :
570 0 : NPN_SetCurrentAsyncSurface(npp, instanceData->backBuffer, NULL);
571 0 : NPAsyncSurface *oldFront = instanceData->frontBuffer;
572 0 : instanceData->frontBuffer = instanceData->backBuffer;
573 0 : instanceData->backBuffer = oldFront;
574 0 : }
575 :
576 : //
577 : // function signatures
578 : //
579 :
580 : NPObject* scriptableAllocate(NPP npp, NPClass* aClass);
581 : void scriptableDeallocate(NPObject* npobj);
582 : void scriptableInvalidate(NPObject* npobj);
583 : bool scriptableHasMethod(NPObject* npobj, NPIdentifier name);
584 : bool scriptableInvoke(NPObject* npobj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result);
585 : bool scriptableInvokeDefault(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
586 : bool scriptableHasProperty(NPObject* npobj, NPIdentifier name);
587 : bool scriptableGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result);
588 : bool scriptableSetProperty(NPObject* npobj, NPIdentifier name, const NPVariant* value);
589 : bool scriptableRemoveProperty(NPObject* npobj, NPIdentifier name);
590 : bool scriptableEnumerate(NPObject* npobj, NPIdentifier** identifier, uint32_t* count);
591 : bool scriptableConstruct(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
592 :
593 : //
594 : // npapi plugin functions
595 : //
596 :
597 : #ifdef XP_UNIX
598 : NP_EXPORT(char*)
599 173 : NP_GetPluginVersion()
600 : {
601 173 : return sPluginVersion;
602 : }
603 : #endif
604 :
605 : static char sMimeDescription[] = "application/x-test:tst:Test mimetype";
606 :
607 : #if defined(XP_UNIX)
608 173 : NP_EXPORT(const char*) NP_GetMIMEDescription()
609 : #elif defined(XP_WIN) || defined(XP_OS2)
610 : const char* NP_GetMIMEDescription()
611 : #endif
612 : {
613 173 : return sMimeDescription;
614 : }
615 :
616 : #ifdef XP_UNIX
617 : NP_EXPORT(NPError)
618 346 : NP_GetValue(void* future, NPPVariable aVariable, void* aValue) {
619 346 : switch (aVariable) {
620 : case NPPVpluginNameString:
621 173 : *((char**)aValue) = sPluginName;
622 173 : break;
623 : case NPPVpluginDescriptionString:
624 173 : *((char**)aValue) = sPluginDescription;
625 173 : break;
626 : default:
627 0 : return NPERR_INVALID_PARAM;
628 : break;
629 : }
630 346 : return NPERR_NO_ERROR;
631 : }
632 : #endif
633 :
634 0 : static bool fillPluginFunctionTable(NPPluginFuncs* pFuncs)
635 : {
636 : // Check the size of the provided structure based on the offset of the
637 : // last member we need.
638 0 : if (pFuncs->size < (offsetof(NPPluginFuncs, getsiteswithdata) + sizeof(void*)))
639 0 : return false;
640 :
641 0 : pFuncs->newp = NPP_New;
642 0 : pFuncs->destroy = NPP_Destroy;
643 0 : pFuncs->setwindow = NPP_SetWindow;
644 0 : pFuncs->newstream = NPP_NewStream;
645 0 : pFuncs->destroystream = NPP_DestroyStream;
646 0 : pFuncs->asfile = NPP_StreamAsFile;
647 0 : pFuncs->writeready = NPP_WriteReady;
648 0 : pFuncs->write = NPP_Write;
649 0 : pFuncs->print = NPP_Print;
650 0 : pFuncs->event = NPP_HandleEvent;
651 0 : pFuncs->urlnotify = NPP_URLNotify;
652 0 : pFuncs->getvalue = NPP_GetValue;
653 0 : pFuncs->setvalue = NPP_SetValue;
654 0 : pFuncs->urlredirectnotify = NPP_URLRedirectNotify;
655 0 : pFuncs->clearsitedata = NPP_ClearSiteData;
656 0 : pFuncs->getsiteswithdata = NPP_GetSitesWithData;
657 :
658 0 : return true;
659 : }
660 :
661 : #if defined(XP_MACOSX)
662 : NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs)
663 : #elif defined(XP_WIN) || defined(XP_OS2)
664 : NPError OSCALL NP_Initialize(NPNetscapeFuncs* bFuncs)
665 : #elif defined(XP_UNIX)
666 0 : NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs)
667 : #endif
668 : {
669 0 : sBrowserFuncs = bFuncs;
670 :
671 0 : initializeIdentifiers();
672 :
673 0 : for (unsigned int i = 0; i < ARRAY_LENGTH(sPluginPropertyValues); i++) {
674 0 : VOID_TO_NPVARIANT(sPluginPropertyValues[i]);
675 : }
676 :
677 0 : memset(&sNPClass, 0, sizeof(NPClass));
678 0 : sNPClass.structVersion = NP_CLASS_STRUCT_VERSION;
679 0 : sNPClass.allocate = (NPAllocateFunctionPtr)scriptableAllocate;
680 0 : sNPClass.deallocate = (NPDeallocateFunctionPtr)scriptableDeallocate;
681 0 : sNPClass.invalidate = (NPInvalidateFunctionPtr)scriptableInvalidate;
682 0 : sNPClass.hasMethod = (NPHasMethodFunctionPtr)scriptableHasMethod;
683 0 : sNPClass.invoke = (NPInvokeFunctionPtr)scriptableInvoke;
684 0 : sNPClass.invokeDefault = (NPInvokeDefaultFunctionPtr)scriptableInvokeDefault;
685 0 : sNPClass.hasProperty = (NPHasPropertyFunctionPtr)scriptableHasProperty;
686 0 : sNPClass.getProperty = (NPGetPropertyFunctionPtr)scriptableGetProperty;
687 0 : sNPClass.setProperty = (NPSetPropertyFunctionPtr)scriptableSetProperty;
688 0 : sNPClass.removeProperty = (NPRemovePropertyFunctionPtr)scriptableRemoveProperty;
689 0 : sNPClass.enumerate = (NPEnumerationFunctionPtr)scriptableEnumerate;
690 0 : sNPClass.construct = (NPConstructFunctionPtr)scriptableConstruct;
691 :
692 : #if defined(XP_UNIX) && !defined(XP_MACOSX)
693 0 : if (!fillPluginFunctionTable(pFuncs)) {
694 0 : return NPERR_INVALID_FUNCTABLE_ERROR;
695 : }
696 : #endif
697 :
698 0 : return NPERR_NO_ERROR;
699 : }
700 :
701 : #if defined(XP_MACOSX)
702 : NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs)
703 : #elif defined(XP_WIN) || defined(XP_OS2)
704 : NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs)
705 : #endif
706 : #if defined(XP_MACOSX) || defined(XP_WIN) || defined(XP_OS2)
707 : {
708 : if (!fillPluginFunctionTable(pFuncs)) {
709 : return NPERR_INVALID_FUNCTABLE_ERROR;
710 : }
711 :
712 : return NPERR_NO_ERROR;
713 : }
714 : #endif
715 :
716 : #if defined(XP_UNIX)
717 0 : NP_EXPORT(NPError) NP_Shutdown()
718 : #elif defined(XP_WIN) || defined(XP_OS2)
719 : NPError OSCALL NP_Shutdown()
720 : #endif
721 : {
722 0 : clearIdentifiers();
723 :
724 0 : for (unsigned int i = 0; i < ARRAY_LENGTH(sPluginPropertyValues); i++) {
725 0 : NPN_ReleaseVariantValue(&sPluginPropertyValues[i]);
726 : }
727 :
728 0 : return NPERR_NO_ERROR;
729 : }
730 :
731 : NPError
732 0 : NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved)
733 : {
734 : // Make sure our pdata field is NULL at this point. If it isn't, that
735 : // probably means the browser gave us uninitialized memory.
736 0 : if (instance->pdata) {
737 0 : printf("NPP_New called with non-NULL NPP->pdata pointer!\n");
738 0 : return NPERR_GENERIC_ERROR;
739 : }
740 :
741 : // Make sure we can render this plugin
742 0 : NPBool browserSupportsWindowless = false;
743 0 : NPN_GetValue(instance, NPNVSupportsWindowless, &browserSupportsWindowless);
744 0 : if (!browserSupportsWindowless && !pluginSupportsWindowMode()) {
745 0 : printf("Windowless mode not supported by the browser, windowed mode not supported by the plugin!\n");
746 0 : return NPERR_GENERIC_ERROR;
747 : }
748 :
749 : // set up our our instance data
750 0 : InstanceData* instanceData = new InstanceData;
751 0 : if (!instanceData)
752 0 : return NPERR_OUT_OF_MEMORY_ERROR;
753 0 : instanceData->npp = instance;
754 0 : instanceData->streamMode = NP_ASFILEONLY;
755 0 : instanceData->testFunction = FUNCTION_NONE;
756 0 : instanceData->functionToFail = FUNCTION_NONE;
757 0 : instanceData->failureCode = 0;
758 0 : instanceData->callOnDestroy = NULL;
759 0 : instanceData->streamChunkSize = 1024;
760 0 : instanceData->streamBuf = NULL;
761 0 : instanceData->streamBufSize = 0;
762 0 : instanceData->fileBuf = NULL;
763 0 : instanceData->fileBufSize = 0;
764 0 : instanceData->throwOnNextInvoke = false;
765 0 : instanceData->runScriptOnPaint = false;
766 0 : instanceData->testrange = NULL;
767 0 : instanceData->hasWidget = false;
768 0 : instanceData->npnNewStream = false;
769 0 : instanceData->invalidateDuringPaint = false;
770 0 : instanceData->writeCount = 0;
771 0 : instanceData->writeReadyCount = 0;
772 0 : memset(&instanceData->window, 0, sizeof(instanceData->window));
773 0 : instanceData->crashOnDestroy = false;
774 0 : instanceData->cleanupWidget = true; // only used by nptest_gtk
775 0 : instanceData->topLevelWindowActivationState = ACTIVATION_STATE_UNKNOWN;
776 0 : instanceData->topLevelWindowActivationEventCount = 0;
777 0 : instanceData->focusState = ACTIVATION_STATE_UNKNOWN;
778 0 : instanceData->focusEventCount = 0;
779 0 : instanceData->eventModel = 0;
780 0 : instanceData->closeStream = false;
781 0 : instanceData->wantsAllStreams = false;
782 0 : instanceData->asyncDrawing = AD_NONE;
783 0 : instanceData->frontBuffer = NULL;
784 0 : instanceData->backBuffer = NULL;
785 0 : instance->pdata = instanceData;
786 :
787 0 : TestNPObject* scriptableObject = (TestNPObject*)NPN_CreateObject(instance, &sNPClass);
788 0 : if (!scriptableObject) {
789 0 : printf("NPN_CreateObject failed to create an object, can't create a plugin instance\n");
790 0 : free(instanceData);
791 0 : return NPERR_GENERIC_ERROR;
792 : }
793 0 : scriptableObject->npp = instance;
794 0 : scriptableObject->drawMode = DM_DEFAULT;
795 0 : scriptableObject->drawColor = 0;
796 0 : instanceData->scriptableObject = scriptableObject;
797 :
798 0 : instanceData->instanceCountWatchGeneration = sCurrentInstanceCountWatchGeneration;
799 :
800 0 : if (NP_FULL == mode) {
801 0 : instanceData->streamMode = NP_SEEK;
802 0 : instanceData->frame = "testframe";
803 0 : addRange(instanceData, "100,100");
804 : }
805 :
806 0 : bool requestWindow = false;
807 : // handle extra params
808 0 : for (int i = 0; i < argc; i++) {
809 0 : if (strcmp(argn[i], "drawmode") == 0) {
810 0 : if (strcmp(argv[i], "solid") == 0)
811 0 : scriptableObject->drawMode = DM_SOLID_COLOR;
812 : }
813 0 : else if (strcmp(argn[i], "color") == 0) {
814 0 : scriptableObject->drawColor = parseHexColor(argv[i], strlen(argv[i]));
815 : }
816 0 : else if (strcmp(argn[i], "wmode") == 0) {
817 0 : if (strcmp(argv[i], "window") == 0) {
818 0 : requestWindow = true;
819 : }
820 : }
821 0 : else if (strcmp(argn[i], "asyncmodel") == 0) {
822 0 : if (strcmp(argv[i], "bitmap") == 0) {
823 0 : if (pluginSupportsAsyncBitmapDrawing()) {
824 0 : instanceData->asyncDrawing = AD_BITMAP;
825 : }
826 : }
827 : }
828 0 : if (strcmp(argn[i], "streammode") == 0) {
829 0 : if (strcmp(argv[i], "normal") == 0) {
830 0 : instanceData->streamMode = NP_NORMAL;
831 : }
832 0 : else if ((strcmp(argv[i], "asfile") == 0) &&
833 0 : strlen(argv[i]) == strlen("asfile")) {
834 0 : instanceData->streamMode = NP_ASFILE;
835 : }
836 0 : else if (strcmp(argv[i], "asfileonly") == 0) {
837 0 : instanceData->streamMode = NP_ASFILEONLY;
838 : }
839 0 : else if (strcmp(argv[i], "seek") == 0) {
840 0 : instanceData->streamMode = NP_SEEK;
841 : }
842 : }
843 0 : if (strcmp(argn[i], "streamchunksize") == 0) {
844 0 : instanceData->streamChunkSize = atoi(argv[i]);
845 : }
846 0 : if (strcmp(argn[i], "failurecode") == 0) {
847 0 : instanceData->failureCode = atoi(argv[i]);
848 : }
849 0 : if (strcmp(argn[i], "functiontofail") == 0) {
850 0 : instanceData->functionToFail = getFuncFromString(argv[i]);
851 : }
852 0 : if (strcmp(argn[i], "geturl") == 0) {
853 0 : instanceData->testUrl = argv[i];
854 0 : instanceData->testFunction = FUNCTION_NPP_GETURL;
855 : }
856 0 : if (strcmp(argn[i], "posturl") == 0) {
857 0 : instanceData->testUrl = argv[i];
858 0 : instanceData->testFunction = FUNCTION_NPP_POSTURL;
859 : }
860 0 : if (strcmp(argn[i], "geturlnotify") == 0) {
861 0 : instanceData->testUrl = argv[i];
862 0 : instanceData->testFunction = FUNCTION_NPP_GETURLNOTIFY;
863 : }
864 0 : if (strcmp(argn[i], "postmode") == 0) {
865 0 : if (strcmp(argv[i], "frame") == 0) {
866 0 : instanceData->postMode = POSTMODE_FRAME;
867 : }
868 0 : else if (strcmp(argv[i], "stream") == 0) {
869 0 : instanceData->postMode = POSTMODE_STREAM;
870 : }
871 : }
872 0 : if (strcmp(argn[i], "frame") == 0) {
873 0 : instanceData->frame = argv[i];
874 : }
875 0 : if (strcmp(argn[i], "range") == 0) {
876 0 : string range = argv[i];
877 0 : size_t semicolon = range.find(';');
878 0 : while (semicolon != string::npos) {
879 0 : addRange(instanceData, range.substr(0, semicolon).c_str());
880 0 : if (semicolon == range.length()) {
881 0 : range = "";
882 0 : break;
883 : }
884 0 : range = range.substr(semicolon + 1);
885 0 : semicolon = range.find(';');
886 : }
887 0 : if (range.length()) addRange(instanceData, range.c_str());
888 : }
889 0 : if (strcmp(argn[i], "newstream") == 0 &&
890 0 : strcmp(argv[i], "true") == 0) {
891 0 : instanceData->npnNewStream = true;
892 : }
893 0 : if (strcmp(argn[i], "newcrash") == 0) {
894 0 : IntentionalCrash();
895 : }
896 0 : if (strcmp(argn[i], "paintscript") == 0) {
897 0 : instanceData->runScriptOnPaint = true;
898 : }
899 : // "cleanupwidget" is only used with nptest_gtk, defaulting to true. It
900 : // indicates whether the plugin should destroy its window in response to
901 : // NPP_Destroy (or let the platform destroy the widget when the parent
902 : // window gets destroyed).
903 0 : if (strcmp(argn[i], "cleanupwidget") == 0 &&
904 0 : strcmp(argv[i], "false") == 0) {
905 0 : instanceData->cleanupWidget = false;
906 : }
907 0 : if (!strcmp(argn[i], "closestream")) {
908 0 : instanceData->closeStream = true;
909 : }
910 : }
911 :
912 0 : if (!browserSupportsWindowless || !pluginSupportsWindowlessMode()) {
913 0 : requestWindow = true;
914 0 : } else if (!pluginSupportsWindowMode()) {
915 0 : requestWindow = false;
916 : }
917 0 : if (requestWindow) {
918 0 : instanceData->hasWidget = true;
919 : } else {
920 : // NPPVpluginWindowBool should default to true, so we may as well
921 : // test that by not setting it in the window case
922 0 : NPN_SetValue(instance, NPPVpluginWindowBool, (void*)false);
923 : }
924 :
925 0 : if (scriptableObject->drawMode == DM_SOLID_COLOR &&
926 : (scriptableObject->drawColor & 0xFF000000) != 0xFF000000) {
927 0 : NPN_SetValue(instance, NPPVpluginTransparentBool, (void*)true);
928 : }
929 :
930 0 : if (instanceData->asyncDrawing == AD_BITMAP) {
931 0 : NPBool supportsAsyncBitmap = false;
932 0 : if ((NPN_GetValue(instance, NPNVsupportsAsyncBitmapSurfaceBool, &supportsAsyncBitmap) == NPERR_NO_ERROR) &&
933 : supportsAsyncBitmap) {
934 0 : NPN_SetValue(instance, NPPVpluginDrawingModel, (void*)NPDrawingModelAsyncBitmapSurface);
935 : } else {
936 0 : instanceData->asyncDrawing = AD_NONE;
937 : }
938 : }
939 :
940 0 : instanceData->lastReportedPrivateModeState = false;
941 0 : instanceData->lastMouseX = instanceData->lastMouseY = -1;
942 0 : instanceData->widthAtLastPaint = -1;
943 0 : instanceData->paintCount = 0;
944 :
945 : // do platform-specific initialization
946 0 : NPError err = pluginInstanceInit(instanceData);
947 0 : if (err != NPERR_NO_ERROR) {
948 0 : NPN_ReleaseObject(scriptableObject);
949 0 : free(instanceData);
950 0 : return err;
951 : }
952 :
953 : NPVariant variantTrue;
954 0 : BOOLEAN_TO_NPVARIANT(true, variantTrue);
955 :
956 : // Set a property on NPNVPluginElementNPObject
957 0 : NPObject* o = NULL;
958 0 : err = NPN_GetValue(instance, NPNVPluginElementNPObject, &o);
959 0 : if (err == NPERR_NO_ERROR) {
960 : NPN_SetProperty(instance, o,
961 0 : NPN_GetStringIdentifier("pluginFoundElement"), &variantTrue);
962 0 : NPN_ReleaseObject(o);
963 0 : o = NULL;
964 : }
965 :
966 : // Set a property on NPNVWindowNPObject
967 0 : err = NPN_GetValue(instance, NPNVWindowNPObject, &o);
968 0 : if (err == NPERR_NO_ERROR) {
969 : NPN_SetProperty(instance, o,
970 0 : NPN_GetStringIdentifier("pluginFoundWindow"), &variantTrue);
971 0 : NPN_ReleaseObject(o);
972 0 : o = NULL;
973 : }
974 :
975 0 : ++sInstanceCount;
976 :
977 0 : if (instanceData->testFunction == FUNCTION_NPP_GETURL) {
978 0 : NPError err = NPN_GetURL(instance, instanceData->testUrl.c_str(), NULL);
979 0 : if (err != NPERR_NO_ERROR) {
980 0 : instanceData->err << "NPN_GetURL returned " << err;
981 : }
982 : }
983 0 : else if (instanceData->testFunction == FUNCTION_NPP_GETURLNOTIFY) {
984 : NPError err = NPN_GetURLNotify(instance, instanceData->testUrl.c_str(),
985 0 : NULL, static_cast<void*>(&kNotifyData));
986 0 : if (err != NPERR_NO_ERROR) {
987 0 : instanceData->err << "NPN_GetURLNotify returned " << err;
988 : }
989 : }
990 :
991 0 : return NPERR_NO_ERROR;
992 : }
993 :
994 : NPError
995 0 : NPP_Destroy(NPP instance, NPSavedData** save)
996 : {
997 0 : printf("NPP_Destroy\n");
998 0 : InstanceData* instanceData = (InstanceData*)(instance->pdata);
999 :
1000 0 : if (instanceData->crashOnDestroy)
1001 0 : IntentionalCrash();
1002 :
1003 0 : if (instanceData->callOnDestroy) {
1004 : NPVariant result;
1005 0 : NPN_InvokeDefault(instance, instanceData->callOnDestroy, NULL, 0, &result);
1006 0 : NPN_ReleaseVariantValue(&result);
1007 0 : NPN_ReleaseObject(instanceData->callOnDestroy);
1008 : }
1009 :
1010 0 : if (instanceData->streamBuf) {
1011 0 : free(instanceData->streamBuf);
1012 : }
1013 0 : if (instanceData->fileBuf) {
1014 0 : free(instanceData->fileBuf);
1015 : }
1016 :
1017 0 : TestRange* currentrange = instanceData->testrange;
1018 : TestRange* nextrange;
1019 0 : while (currentrange != NULL) {
1020 0 : nextrange = reinterpret_cast<TestRange*>(currentrange->next);
1021 0 : delete currentrange;
1022 0 : currentrange = nextrange;
1023 : }
1024 :
1025 0 : if (instanceData->frontBuffer) {
1026 0 : NPN_SetCurrentAsyncSurface(instance, NULL, NULL);
1027 0 : NPN_FinalizeAsyncSurface(instance, instanceData->frontBuffer);
1028 0 : NPN_MemFree(instanceData->frontBuffer);
1029 : }
1030 0 : if (instanceData->backBuffer) {
1031 0 : NPN_FinalizeAsyncSurface(instance, instanceData->backBuffer);
1032 0 : NPN_MemFree(instanceData->backBuffer);
1033 : }
1034 :
1035 0 : pluginInstanceShutdown(instanceData);
1036 0 : NPN_ReleaseObject(instanceData->scriptableObject);
1037 :
1038 0 : if (sCurrentInstanceCountWatchGeneration == instanceData->instanceCountWatchGeneration) {
1039 0 : --sInstanceCount;
1040 : }
1041 0 : delete instanceData;
1042 :
1043 0 : return NPERR_NO_ERROR;
1044 : }
1045 :
1046 : NPError
1047 0 : NPP_SetWindow(NPP instance, NPWindow* window)
1048 : {
1049 0 : InstanceData* instanceData = (InstanceData*)(instance->pdata);
1050 :
1051 0 : if (instanceData->scriptableObject->drawMode == DM_DEFAULT &&
1052 : (instanceData->window.width != window->width ||
1053 : instanceData->window.height != window->height)) {
1054 : NPRect r;
1055 0 : r.left = r.top = 0;
1056 0 : r.right = window->width;
1057 0 : r.bottom = window->height;
1058 0 : NPN_InvalidateRect(instance, &r);
1059 : }
1060 :
1061 0 : void* oldWindow = instanceData->window.window;
1062 0 : pluginDoSetWindow(instanceData, window);
1063 0 : if (instanceData->hasWidget && oldWindow != instanceData->window.window) {
1064 0 : pluginWidgetInit(instanceData, oldWindow);
1065 : }
1066 :
1067 0 : if (instanceData->asyncDrawing == AD_BITMAP) {
1068 0 : if (instanceData->frontBuffer &&
1069 : instanceData->frontBuffer->size.width == window->width &&
1070 : instanceData->frontBuffer->size.height == window->height) {
1071 0 : return NPERR_NO_ERROR;
1072 : }
1073 0 : if (instanceData->frontBuffer) {
1074 0 : NPN_FinalizeAsyncSurface(instance, instanceData->frontBuffer);
1075 0 : NPN_MemFree(instanceData->frontBuffer);
1076 : }
1077 0 : if (instanceData->backBuffer) {
1078 0 : NPN_FinalizeAsyncSurface(instance, instanceData->backBuffer);
1079 0 : NPN_MemFree(instanceData->backBuffer);
1080 : }
1081 0 : instanceData->frontBuffer = (NPAsyncSurface*)NPN_MemAlloc(sizeof(NPAsyncSurface));
1082 0 : instanceData->backBuffer = (NPAsyncSurface*)NPN_MemAlloc(sizeof(NPAsyncSurface));
1083 :
1084 : NPSize size;
1085 0 : size.width = window->width;
1086 0 : size.height = window->height;
1087 :
1088 0 : memcpy(instanceData->backBuffer, instanceData->frontBuffer, sizeof(NPAsyncSurface));
1089 :
1090 0 : NPN_InitAsyncSurface(instance, &size, NPImageFormatBGRA32, NULL, instanceData->frontBuffer);
1091 0 : NPN_InitAsyncSurface(instance, &size, NPImageFormatBGRA32, NULL, instanceData->backBuffer);
1092 :
1093 0 : drawAsyncBitmapColor(instanceData);
1094 : }
1095 0 : return NPERR_NO_ERROR;
1096 : }
1097 :
1098 : NPError
1099 0 : NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype)
1100 : {
1101 0 : printf("NPP_NewStream\n");
1102 0 : InstanceData* instanceData = (InstanceData*)(instance->pdata);
1103 :
1104 0 : if (instanceData->functionToFail == FUNCTION_NPP_NEWSTREAM &&
1105 : instanceData->failureCode) {
1106 0 : instanceData->err << SUCCESS_STRING;
1107 0 : if (instanceData->frame.length() > 0) {
1108 0 : sendBufferToFrame(instance);
1109 : }
1110 0 : return instanceData->failureCode;
1111 : }
1112 :
1113 0 : if (stream->notifyData &&
1114 : static_cast<URLNotifyData*>(stream->notifyData) != &kNotifyData) {
1115 : // stream from streamTest
1116 0 : *stype = NP_NORMAL;
1117 : }
1118 : else {
1119 0 : *stype = instanceData->streamMode;
1120 :
1121 0 : if (instanceData->streamBufSize) {
1122 0 : free(instanceData->streamBuf);
1123 0 : instanceData->streamBufSize = 0;
1124 0 : if (instanceData->testFunction == FUNCTION_NPP_POSTURL &&
1125 : instanceData->postMode == POSTMODE_STREAM) {
1126 0 : instanceData->testFunction = FUNCTION_NPP_GETURL;
1127 : }
1128 : else {
1129 : // We already got a stream and didn't ask for another one.
1130 0 : instanceData->err << "Received unexpected multiple NPP_NewStream";
1131 : }
1132 : }
1133 : }
1134 0 : return NPERR_NO_ERROR;
1135 : }
1136 :
1137 : NPError
1138 0 : NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
1139 : {
1140 0 : printf("NPP_DestroyStream\n");
1141 0 : InstanceData* instanceData = (InstanceData*)(instance->pdata);
1142 :
1143 0 : if (instanceData->functionToFail == FUNCTION_NPP_NEWSTREAM) {
1144 0 : instanceData->err << "NPP_DestroyStream called";
1145 : }
1146 :
1147 0 : if (instanceData->functionToFail == FUNCTION_NPP_WRITE) {
1148 0 : if (instanceData->writeCount == 1)
1149 0 : instanceData->err << SUCCESS_STRING;
1150 : else
1151 0 : instanceData->err << "NPP_Write called after returning -1";
1152 : }
1153 :
1154 0 : if (instanceData->functionToFail == FUNCTION_NPP_DESTROYSTREAM &&
1155 : instanceData->failureCode) {
1156 0 : instanceData->err << SUCCESS_STRING;
1157 0 : if (instanceData->frame.length() > 0) {
1158 0 : sendBufferToFrame(instance);
1159 : }
1160 0 : return instanceData->failureCode;
1161 : }
1162 :
1163 0 : URLNotifyData* nd = static_cast<URLNotifyData*>(stream->notifyData);
1164 0 : if (nd && nd != &kNotifyData) {
1165 0 : return NPERR_NO_ERROR;
1166 : }
1167 :
1168 0 : if (instanceData->streamMode == NP_ASFILE &&
1169 : instanceData->functionToFail == FUNCTION_NONE) {
1170 0 : if (!instanceData->streamBuf) {
1171 : instanceData->err <<
1172 0 : "Error: no data written with NPP_Write";
1173 0 : return NPERR_GENERIC_ERROR;
1174 : }
1175 :
1176 0 : if (!instanceData->fileBuf) {
1177 : instanceData->err <<
1178 0 : "Error: no data written with NPP_StreamAsFile";
1179 0 : return NPERR_GENERIC_ERROR;
1180 : }
1181 :
1182 0 : if (strcmp(reinterpret_cast<char *>(instanceData->fileBuf),
1183 0 : reinterpret_cast<char *>(instanceData->streamBuf))) {
1184 : instanceData->err <<
1185 0 : "Error: data passed to NPP_Write and NPP_StreamAsFile differed";
1186 : }
1187 : }
1188 0 : if (instanceData->frame.length() > 0 &&
1189 : instanceData->testFunction != FUNCTION_NPP_GETURLNOTIFY &&
1190 : instanceData->testFunction != FUNCTION_NPP_POSTURL) {
1191 0 : sendBufferToFrame(instance);
1192 : }
1193 0 : if (instanceData->testFunction == FUNCTION_NPP_POSTURL) {
1194 : NPError err = NPN_PostURL(instance, instanceData->testUrl.c_str(),
1195 0 : instanceData->postMode == POSTMODE_FRAME ? instanceData->frame.c_str() : NULL,
1196 : instanceData->streamBufSize,
1197 0 : reinterpret_cast<char *>(instanceData->streamBuf), false);
1198 0 : if (err != NPERR_NO_ERROR)
1199 0 : instanceData->err << "Error: NPN_PostURL returned error value " << err;
1200 : }
1201 0 : return NPERR_NO_ERROR;
1202 : }
1203 :
1204 : int32_t
1205 0 : NPP_WriteReady(NPP instance, NPStream* stream)
1206 : {
1207 0 : printf("NPP_WriteReady\n");
1208 0 : InstanceData* instanceData = (InstanceData*)(instance->pdata);
1209 0 : instanceData->writeReadyCount++;
1210 0 : if (instanceData->functionToFail == FUNCTION_NPP_NEWSTREAM) {
1211 0 : instanceData->err << "NPP_WriteReady called";
1212 : }
1213 :
1214 : // temporarily disabled per bug 519870
1215 : //if (instanceData->writeReadyCount == 1) {
1216 : // return 0;
1217 : //}
1218 :
1219 0 : return instanceData->streamChunkSize;
1220 : }
1221 :
1222 : int32_t
1223 0 : NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer)
1224 : {
1225 0 : InstanceData* instanceData = (InstanceData*)(instance->pdata);
1226 0 : instanceData->writeCount++;
1227 :
1228 : // temporarily disabled per bug 519870
1229 : //if (instanceData->writeReadyCount == 1) {
1230 : // instanceData->err << "NPP_Write called even though NPP_WriteReady " <<
1231 : // "returned 0";
1232 : //}
1233 :
1234 0 : if (instanceData->functionToFail == FUNCTION_NPP_WRITE_RPC) {
1235 : // Make an RPC call and pretend to consume the data
1236 0 : NPObject* windowObject = NULL;
1237 0 : NPN_GetValue(instance, NPNVWindowNPObject, &windowObject);
1238 0 : if (windowObject)
1239 0 : NPN_ReleaseObject(windowObject);
1240 :
1241 0 : return len;
1242 : }
1243 :
1244 0 : if (instanceData->functionToFail == FUNCTION_NPP_NEWSTREAM) {
1245 0 : instanceData->err << "NPP_Write called";
1246 : }
1247 :
1248 0 : if (instanceData->functionToFail == FUNCTION_NPP_WRITE) {
1249 0 : return -1;
1250 : }
1251 :
1252 0 : URLNotifyData* nd = static_cast<URLNotifyData*>(stream->notifyData);
1253 :
1254 0 : if (nd && nd->writeCallback) {
1255 : NPVariant args[1];
1256 0 : STRINGN_TO_NPVARIANT(stream->url, strlen(stream->url), args[0]);
1257 :
1258 : NPVariant result;
1259 0 : NPN_InvokeDefault(instance, nd->writeCallback, args, 1, &result);
1260 0 : NPN_ReleaseVariantValue(&result);
1261 : }
1262 :
1263 0 : if (nd && nd != &kNotifyData) {
1264 0 : uint32_t newsize = nd->size + len;
1265 0 : nd->data = (char*) realloc(nd->data, newsize);
1266 0 : memcpy(nd->data + nd->size, buffer, len);
1267 0 : nd->size = newsize;
1268 0 : return len;
1269 : }
1270 :
1271 0 : if (instanceData->closeStream) {
1272 0 : instanceData->closeStream = false;
1273 0 : if (instanceData->testrange != NULL) {
1274 0 : NPN_RequestRead(stream, instanceData->testrange);
1275 : }
1276 0 : NPN_DestroyStream(instance, stream, NPRES_USER_BREAK);
1277 : }
1278 0 : else if (instanceData->streamMode == NP_SEEK &&
1279 : stream->end != 0 &&
1280 : stream->end == ((uint32_t)instanceData->streamBufSize + len)) {
1281 : // If the complete stream has been written, and we're doing a seek test,
1282 : // then call NPN_RequestRead.
1283 : // prevent recursion
1284 0 : instanceData->streamMode = NP_NORMAL;
1285 :
1286 0 : if (instanceData->testrange != NULL) {
1287 0 : NPError err = NPN_RequestRead(stream, instanceData->testrange);
1288 0 : if (err != NPERR_NO_ERROR) {
1289 0 : instanceData->err << "NPN_RequestRead returned error %d" << err;
1290 : }
1291 0 : printf("called NPN_RequestRead, return %d\n", err);
1292 : }
1293 : }
1294 :
1295 0 : char* streamBuf = reinterpret_cast<char *>(instanceData->streamBuf);
1296 0 : if (offset + len <= instanceData->streamBufSize) {
1297 0 : if (memcmp(buffer, streamBuf + offset, len)) {
1298 : instanceData->err <<
1299 0 : "Error: data written from NPN_RequestRead doesn't match";
1300 : }
1301 : else {
1302 0 : printf("data matches!\n");
1303 : }
1304 0 : TestRange* range = instanceData->testrange;
1305 0 : bool stillwaiting = false;
1306 0 : while(range != NULL) {
1307 0 : if (offset == range->offset &&
1308 : (uint32_t)len == range->length) {
1309 0 : range->waiting = false;
1310 : }
1311 0 : if (range->waiting) stillwaiting = true;
1312 0 : range = reinterpret_cast<TestRange*>(range->next);
1313 : }
1314 0 : if (!stillwaiting) {
1315 0 : NPError err = NPN_DestroyStream(instance, stream, NPRES_DONE);
1316 0 : if (err != NPERR_NO_ERROR) {
1317 0 : instanceData->err << "Error: NPN_DestroyStream returned " << err;
1318 : }
1319 : }
1320 : }
1321 : else {
1322 0 : if (instanceData->streamBufSize == 0) {
1323 0 : instanceData->streamBuf = malloc(len + 1);
1324 0 : streamBuf = reinterpret_cast<char *>(instanceData->streamBuf);
1325 : }
1326 : else {
1327 : instanceData->streamBuf =
1328 : realloc(reinterpret_cast<char *>(instanceData->streamBuf),
1329 0 : instanceData->streamBufSize + len + 1);
1330 0 : streamBuf = reinterpret_cast<char *>(instanceData->streamBuf);
1331 : }
1332 0 : memcpy(streamBuf + instanceData->streamBufSize, buffer, len);
1333 0 : instanceData->streamBufSize = instanceData->streamBufSize + len;
1334 0 : streamBuf[instanceData->streamBufSize] = '\0';
1335 : }
1336 0 : return len;
1337 : }
1338 :
1339 : void
1340 0 : NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
1341 : {
1342 0 : printf("NPP_StreamAsFile, file=%s\n", fname);
1343 : size_t size;
1344 :
1345 0 : InstanceData* instanceData = (InstanceData*)(instance->pdata);
1346 :
1347 0 : if (instanceData->functionToFail == FUNCTION_NPP_NEWSTREAM ||
1348 : instanceData->functionToFail == FUNCTION_NPP_WRITE) {
1349 0 : instanceData->err << "NPP_StreamAsFile called";
1350 : }
1351 :
1352 0 : if (!fname)
1353 0 : return;
1354 :
1355 0 : FILE *file = fopen(fname, "rb");
1356 0 : if (file) {
1357 0 : fseek(file, 0, SEEK_END);
1358 0 : size = ftell(file);
1359 0 : instanceData->fileBuf = malloc((int32_t)size + 1);
1360 0 : char* buf = reinterpret_cast<char *>(instanceData->fileBuf);
1361 0 : fseek(file, 0, SEEK_SET);
1362 0 : fread(instanceData->fileBuf, 1, size, file);
1363 0 : fclose(file);
1364 0 : buf[size] = '\0';
1365 0 : instanceData->fileBufSize = (int32_t)size;
1366 : }
1367 : else {
1368 0 : printf("Unable to open file\n");
1369 0 : instanceData->err << "Unable to open file " << fname;
1370 : }
1371 : }
1372 :
1373 : void
1374 0 : NPP_Print(NPP instance, NPPrint* platformPrint)
1375 : {
1376 0 : }
1377 :
1378 : int16_t
1379 0 : NPP_HandleEvent(NPP instance, void* event)
1380 : {
1381 0 : InstanceData* instanceData = (InstanceData*)(instance->pdata);
1382 0 : return pluginHandleEvent(instanceData, event);
1383 : }
1384 :
1385 : void
1386 0 : NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
1387 : {
1388 0 : InstanceData* instanceData = (InstanceData*)(instance->pdata);
1389 0 : URLNotifyData* ndata = static_cast<URLNotifyData*>(notifyData);
1390 :
1391 0 : printf("NPP_URLNotify called\n");
1392 0 : if (&kNotifyData == ndata) {
1393 0 : if (instanceData->frame.length() > 0) {
1394 0 : sendBufferToFrame(instance);
1395 : }
1396 : }
1397 0 : else if (!strcmp(ndata->cookie, "dynamic-cookie")) {
1398 0 : if (ndata->notifyCallback) {
1399 : NPVariant args[2];
1400 0 : INT32_TO_NPVARIANT(reason, args[0]);
1401 0 : if (ndata->data) {
1402 0 : STRINGN_TO_NPVARIANT(ndata->data, ndata->size, args[1]);
1403 : }
1404 : else {
1405 0 : STRINGN_TO_NPVARIANT("", 0, args[1]);
1406 : }
1407 :
1408 : NPVariant result;
1409 0 : NPN_InvokeDefault(instance, ndata->notifyCallback, args, 2, &result);
1410 0 : NPN_ReleaseVariantValue(&result);
1411 : }
1412 :
1413 : // clean up the URLNotifyData
1414 0 : if (ndata->writeCallback) {
1415 0 : NPN_ReleaseObject(ndata->writeCallback);
1416 : }
1417 0 : if (ndata->notifyCallback) {
1418 0 : NPN_ReleaseObject(ndata->notifyCallback);
1419 : }
1420 0 : if (ndata->redirectCallback) {
1421 0 : NPN_ReleaseObject(ndata->redirectCallback);
1422 : }
1423 0 : free(ndata->data);
1424 0 : delete ndata;
1425 : }
1426 : else {
1427 0 : printf("ERROR! NPP_URLNotify called with wrong cookie\n");
1428 0 : instanceData->err << "Error: NPP_URLNotify called with wrong cookie";
1429 : }
1430 0 : }
1431 :
1432 : NPError
1433 0 : NPP_GetValue(NPP instance, NPPVariable variable, void* value)
1434 : {
1435 0 : InstanceData* instanceData = (InstanceData*)instance->pdata;
1436 0 : if (variable == NPPVpluginScriptableNPObject) {
1437 0 : NPObject* object = instanceData->scriptableObject;
1438 0 : NPN_RetainObject(object);
1439 0 : *((NPObject**)value) = object;
1440 0 : return NPERR_NO_ERROR;
1441 : }
1442 0 : if (variable == NPPVpluginNeedsXEmbed) {
1443 : // Only relevant for X plugins
1444 0 : *(NPBool*)value = instanceData->hasWidget;
1445 0 : return NPERR_NO_ERROR;
1446 : }
1447 0 : if (variable == NPPVpluginWantsAllNetworkStreams) {
1448 0 : *(NPBool*)value = instanceData->wantsAllStreams;
1449 0 : return NPERR_NO_ERROR;
1450 : }
1451 :
1452 0 : return NPERR_GENERIC_ERROR;
1453 : }
1454 :
1455 : NPError
1456 0 : NPP_SetValue(NPP instance, NPNVariable variable, void* value)
1457 : {
1458 0 : if (variable == NPNVprivateModeBool) {
1459 0 : InstanceData* instanceData = (InstanceData*)(instance->pdata);
1460 0 : instanceData->lastReportedPrivateModeState = bool(*static_cast<NPBool*>(value));
1461 0 : return NPERR_NO_ERROR;
1462 : }
1463 0 : return NPERR_GENERIC_ERROR;
1464 : }
1465 :
1466 : void
1467 0 : NPP_URLRedirectNotify(NPP instance, const char* url, int32_t status, void* notifyData)
1468 : {
1469 0 : if (notifyData) {
1470 0 : URLNotifyData* nd = static_cast<URLNotifyData*>(notifyData);
1471 0 : if (nd->redirectCallback) {
1472 : NPVariant args[2];
1473 0 : STRINGN_TO_NPVARIANT(url, strlen(url), args[0]);
1474 0 : INT32_TO_NPVARIANT(status, args[1]);
1475 :
1476 : NPVariant result;
1477 0 : NPN_InvokeDefault(instance, nd->redirectCallback, args, 2, &result);
1478 0 : NPN_ReleaseVariantValue(&result);
1479 : }
1480 0 : NPN_URLRedirectResponse(instance, notifyData, nd->allowRedirects);
1481 0 : return;
1482 : }
1483 0 : NPN_URLRedirectResponse(instance, notifyData, true);
1484 : }
1485 :
1486 : NPError
1487 0 : NPP_ClearSiteData(const char* site, uint64_t flags, uint64_t maxAge)
1488 : {
1489 0 : if (!sSitesWithData)
1490 0 : return NPERR_NO_ERROR;
1491 :
1492 : // Error condition: no support for clear-by-age
1493 0 : if (!sClearByAgeSupported && maxAge != uint64_t(int64_t(-1)))
1494 0 : return NPERR_TIME_RANGE_NOT_SUPPORTED;
1495 :
1496 : // Iterate over list and remove matches
1497 0 : list<siteData>::iterator iter = sSitesWithData->begin();
1498 0 : list<siteData>::iterator end = sSitesWithData->end();
1499 0 : while (iter != end) {
1500 0 : const siteData& data = *iter;
1501 0 : list<siteData>::iterator next = iter;
1502 0 : ++next;
1503 0 : if ((!site || data.site.compare(site) == 0) &&
1504 : (flags == NP_CLEAR_ALL || data.flags & flags) &&
1505 : data.age <= maxAge) {
1506 0 : sSitesWithData->erase(iter);
1507 : }
1508 0 : iter = next;
1509 : }
1510 :
1511 0 : return NPERR_NO_ERROR;
1512 : }
1513 :
1514 : char**
1515 0 : NPP_GetSitesWithData()
1516 : {
1517 0 : int length = 0;
1518 : char** result;
1519 :
1520 0 : if (sSitesWithData)
1521 0 : length = sSitesWithData->size();
1522 :
1523 : // Allocate the maximum possible size the list could be.
1524 0 : result = static_cast<char**>(NPN_MemAlloc((length + 1) * sizeof(char*)));
1525 0 : result[length] = NULL;
1526 :
1527 0 : if (length == 0) {
1528 : // Represent the no site data case as an array of length 1 with a NULL
1529 : // entry.
1530 0 : return result;
1531 : }
1532 :
1533 : // Iterate the list of stored data, and build a list of strings.
1534 0 : list<string> sites;
1535 : {
1536 0 : list<siteData>::iterator iter = sSitesWithData->begin();
1537 0 : list<siteData>::iterator end = sSitesWithData->end();
1538 0 : for (; iter != end; ++iter) {
1539 0 : const siteData& data = *iter;
1540 0 : sites.push_back(data.site);
1541 : }
1542 : }
1543 :
1544 : // Remove duplicate strings.
1545 0 : sites.sort();
1546 0 : sites.unique();
1547 :
1548 : // Add strings to the result array, and null terminate.
1549 : {
1550 0 : int i = 0;
1551 0 : list<string>::iterator iter = sites.begin();
1552 0 : list<string>::iterator end = sites.end();
1553 0 : for (; iter != end; ++iter, ++i) {
1554 0 : const string& site = *iter;
1555 0 : result[i] = static_cast<char*>(NPN_MemAlloc(site.length() + 1));
1556 0 : memcpy(result[i], site.c_str(), site.length() + 1);
1557 : }
1558 : }
1559 0 : result[sites.size()] = NULL;
1560 :
1561 0 : return result;
1562 : }
1563 :
1564 : //
1565 : // npapi browser functions
1566 : //
1567 :
1568 : bool
1569 0 : NPN_SetProperty(NPP instance, NPObject* obj, NPIdentifier propertyName, const NPVariant* value)
1570 : {
1571 0 : return sBrowserFuncs->setproperty(instance, obj, propertyName, value);
1572 : }
1573 :
1574 : NPIdentifier
1575 0 : NPN_GetIntIdentifier(int32_t intid)
1576 : {
1577 0 : return sBrowserFuncs->getintidentifier(intid);
1578 : }
1579 :
1580 : NPIdentifier
1581 0 : NPN_GetStringIdentifier(const NPUTF8* name)
1582 : {
1583 0 : return sBrowserFuncs->getstringidentifier(name);
1584 : }
1585 :
1586 : void
1587 0 : NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers)
1588 : {
1589 0 : return sBrowserFuncs->getstringidentifiers(names, nameCount, identifiers);
1590 : }
1591 :
1592 : bool
1593 0 : NPN_IdentifierIsString(NPIdentifier identifier)
1594 : {
1595 0 : return sBrowserFuncs->identifierisstring(identifier);
1596 : }
1597 :
1598 : NPUTF8*
1599 0 : NPN_UTF8FromIdentifier(NPIdentifier identifier)
1600 : {
1601 0 : return sBrowserFuncs->utf8fromidentifier(identifier);
1602 : }
1603 :
1604 : int32_t
1605 0 : NPN_IntFromIdentifier(NPIdentifier identifier)
1606 : {
1607 0 : return sBrowserFuncs->intfromidentifier(identifier);
1608 : }
1609 :
1610 : NPError
1611 0 : NPN_GetValue(NPP instance, NPNVariable variable, void* value)
1612 : {
1613 0 : return sBrowserFuncs->getvalue(instance, variable, value);
1614 : }
1615 :
1616 : NPError
1617 0 : NPN_SetValue(NPP instance, NPPVariable variable, void* value)
1618 : {
1619 0 : return sBrowserFuncs->setvalue(instance, variable, value);
1620 : }
1621 :
1622 : void
1623 0 : NPN_InvalidateRect(NPP instance, NPRect* rect)
1624 : {
1625 0 : sBrowserFuncs->invalidaterect(instance, rect);
1626 0 : }
1627 :
1628 : bool
1629 0 : NPN_HasProperty(NPP instance, NPObject* obj, NPIdentifier propertyName)
1630 : {
1631 0 : return sBrowserFuncs->hasproperty(instance, obj, propertyName);
1632 : }
1633 :
1634 : NPObject*
1635 0 : NPN_CreateObject(NPP instance, NPClass* aClass)
1636 : {
1637 0 : return sBrowserFuncs->createobject(instance, aClass);
1638 : }
1639 :
1640 : bool
1641 0 : NPN_Invoke(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result)
1642 : {
1643 0 : return sBrowserFuncs->invoke(npp, obj, methodName, args, argCount, result);
1644 : }
1645 :
1646 : bool
1647 0 : NPN_InvokeDefault(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result)
1648 : {
1649 0 : return sBrowserFuncs->invokeDefault(npp, obj, args, argCount, result);
1650 : }
1651 :
1652 : bool
1653 0 : NPN_Construct(NPP npp, NPObject* npobj, const NPVariant* args,
1654 : uint32_t argCount, NPVariant* result)
1655 : {
1656 0 : return sBrowserFuncs->construct(npp, npobj, args, argCount, result);
1657 : }
1658 :
1659 : const char*
1660 0 : NPN_UserAgent(NPP instance)
1661 : {
1662 0 : return sBrowserFuncs->uagent(instance);
1663 : }
1664 :
1665 : NPObject*
1666 0 : NPN_RetainObject(NPObject* obj)
1667 : {
1668 0 : return sBrowserFuncs->retainobject(obj);
1669 : }
1670 :
1671 : void
1672 0 : NPN_ReleaseObject(NPObject* obj)
1673 : {
1674 0 : return sBrowserFuncs->releaseobject(obj);
1675 : }
1676 :
1677 : void*
1678 0 : NPN_MemAlloc(uint32_t size)
1679 : {
1680 0 : return sBrowserFuncs->memalloc(size);
1681 : }
1682 :
1683 : char*
1684 0 : NPN_StrDup(const char* str)
1685 : {
1686 0 : return strcpy((char*)sBrowserFuncs->memalloc(strlen(str) + 1), str);
1687 : }
1688 :
1689 : void
1690 0 : NPN_MemFree(void* ptr)
1691 : {
1692 0 : return sBrowserFuncs->memfree(ptr);
1693 : }
1694 :
1695 : uint32_t
1696 0 : NPN_ScheduleTimer(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID))
1697 : {
1698 0 : return sBrowserFuncs->scheduletimer(instance, interval, repeat, timerFunc);
1699 : }
1700 :
1701 : void
1702 0 : NPN_UnscheduleTimer(NPP instance, uint32_t timerID)
1703 : {
1704 0 : return sBrowserFuncs->unscheduletimer(instance, timerID);
1705 : }
1706 :
1707 : void
1708 0 : NPN_ReleaseVariantValue(NPVariant *variant)
1709 : {
1710 0 : return sBrowserFuncs->releasevariantvalue(variant);
1711 : }
1712 :
1713 : NPError
1714 0 : NPN_GetURLNotify(NPP instance, const char* url, const char* target, void* notifyData)
1715 : {
1716 0 : return sBrowserFuncs->geturlnotify(instance, url, target, notifyData);
1717 : }
1718 :
1719 : NPError
1720 0 : NPN_GetURL(NPP instance, const char* url, const char* target)
1721 : {
1722 0 : return sBrowserFuncs->geturl(instance, url, target);
1723 : }
1724 :
1725 : NPError
1726 0 : NPN_RequestRead(NPStream* stream, NPByteRange* rangeList)
1727 : {
1728 0 : return sBrowserFuncs->requestread(stream, rangeList);
1729 : }
1730 :
1731 : NPError
1732 0 : NPN_PostURLNotify(NPP instance, const char* url,
1733 : const char* target, uint32_t len,
1734 : const char* buf, NPBool file, void* notifyData)
1735 : {
1736 0 : return sBrowserFuncs->posturlnotify(instance, url, target, len, buf, file, notifyData);
1737 : }
1738 :
1739 : NPError
1740 0 : NPN_PostURL(NPP instance, const char *url,
1741 : const char *target, uint32_t len,
1742 : const char *buf, NPBool file)
1743 : {
1744 0 : return sBrowserFuncs->posturl(instance, url, target, len, buf, file);
1745 : }
1746 :
1747 : NPError
1748 0 : NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason)
1749 : {
1750 0 : return sBrowserFuncs->destroystream(instance, stream, reason);
1751 : }
1752 :
1753 : NPError
1754 0 : NPN_NewStream(NPP instance,
1755 : NPMIMEType type,
1756 : const char* target,
1757 : NPStream** stream)
1758 : {
1759 0 : return sBrowserFuncs->newstream(instance, type, target, stream);
1760 : }
1761 :
1762 : int32_t
1763 0 : NPN_Write(NPP instance,
1764 : NPStream* stream,
1765 : int32_t len,
1766 : void* buf)
1767 : {
1768 0 : return sBrowserFuncs->write(instance, stream, len, buf);
1769 : }
1770 :
1771 : bool
1772 0 : NPN_Enumerate(NPP instance,
1773 : NPObject *npobj,
1774 : NPIdentifier **identifiers,
1775 : uint32_t *identifierCount)
1776 : {
1777 : return sBrowserFuncs->enumerate(instance, npobj, identifiers,
1778 0 : identifierCount);
1779 : }
1780 :
1781 : bool
1782 0 : NPN_GetProperty(NPP instance,
1783 : NPObject *npobj,
1784 : NPIdentifier propertyName,
1785 : NPVariant *result)
1786 : {
1787 0 : return sBrowserFuncs->getproperty(instance, npobj, propertyName, result);
1788 : }
1789 :
1790 : bool
1791 0 : NPN_Evaluate(NPP instance, NPObject *npobj, NPString *script, NPVariant *result)
1792 : {
1793 0 : return sBrowserFuncs->evaluate(instance, npobj, script, result);
1794 : }
1795 :
1796 : void
1797 0 : NPN_SetException(NPObject *npobj, const NPUTF8 *message)
1798 : {
1799 0 : return sBrowserFuncs->setexception(npobj, message);
1800 : }
1801 :
1802 : NPBool
1803 0 : NPN_ConvertPoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace)
1804 : {
1805 0 : return sBrowserFuncs->convertpoint(instance, sourceX, sourceY, sourceSpace, destX, destY, destSpace);
1806 : }
1807 :
1808 : NPError
1809 0 : NPN_SetValueForURL(NPP instance, NPNURLVariable variable, const char *url, const char *value, uint32_t len)
1810 : {
1811 0 : return sBrowserFuncs->setvalueforurl(instance, variable, url, value, len);
1812 : }
1813 :
1814 : NPError
1815 0 : NPN_GetValueForURL(NPP instance, NPNURLVariable variable, const char *url, char **value, uint32_t *len)
1816 : {
1817 0 : return sBrowserFuncs->getvalueforurl(instance, variable, url, value, len);
1818 : }
1819 :
1820 : NPError
1821 0 : NPN_GetAuthenticationInfo(NPP instance,
1822 : const char *protocol,
1823 : const char *host, int32_t port,
1824 : const char *scheme,
1825 : const char *realm,
1826 : char **username, uint32_t *ulen,
1827 : char **password,
1828 : uint32_t *plen)
1829 : {
1830 : return sBrowserFuncs->getauthenticationinfo(instance, protocol, host, port, scheme, realm,
1831 0 : username, ulen, password, plen);
1832 : }
1833 :
1834 : void
1835 0 : NPN_PluginThreadAsyncCall(NPP plugin, void (*func)(void*), void* userdata)
1836 : {
1837 0 : return sBrowserFuncs->pluginthreadasynccall(plugin, func, userdata);
1838 : }
1839 :
1840 : void
1841 0 : NPN_URLRedirectResponse(NPP instance, void* notifyData, NPBool allow)
1842 : {
1843 0 : return sBrowserFuncs->urlredirectresponse(instance, notifyData, allow);
1844 : }
1845 :
1846 : NPError
1847 0 : NPN_InitAsyncSurface(NPP instance, NPSize *size, NPImageFormat format,
1848 : void *initData, NPAsyncSurface *surface)
1849 : {
1850 0 : return sBrowserFuncs->initasyncsurface(instance, size, format, initData, surface);
1851 : }
1852 :
1853 : NPError
1854 0 : NPN_FinalizeAsyncSurface(NPP instance, NPAsyncSurface *surface)
1855 : {
1856 0 : return sBrowserFuncs->finalizeasyncsurface(instance, surface);
1857 : }
1858 :
1859 : void
1860 0 : NPN_SetCurrentAsyncSurface(NPP instance, NPAsyncSurface *surface, NPRect *changed)
1861 : {
1862 0 : sBrowserFuncs->setcurrentasyncsurface(instance, surface, changed);
1863 0 : }
1864 :
1865 : //
1866 : // npruntime object functions
1867 : //
1868 :
1869 : NPObject*
1870 0 : scriptableAllocate(NPP npp, NPClass* aClass)
1871 : {
1872 0 : TestNPObject* object = (TestNPObject*)NPN_MemAlloc(sizeof(TestNPObject));
1873 0 : if (!object)
1874 0 : return NULL;
1875 0 : memset(object, 0, sizeof(TestNPObject));
1876 0 : return object;
1877 : }
1878 :
1879 : void
1880 0 : scriptableDeallocate(NPObject* npobj)
1881 : {
1882 0 : NPN_MemFree(npobj);
1883 0 : }
1884 :
1885 : void
1886 0 : scriptableInvalidate(NPObject* npobj)
1887 : {
1888 0 : }
1889 :
1890 : bool
1891 0 : scriptableHasMethod(NPObject* npobj, NPIdentifier name)
1892 : {
1893 0 : for (int i = 0; i < int(ARRAY_LENGTH(sPluginMethodIdentifiers)); i++) {
1894 0 : if (name == sPluginMethodIdentifiers[i])
1895 0 : return true;
1896 : }
1897 0 : return false;
1898 : }
1899 :
1900 : bool
1901 0 : scriptableInvoke(NPObject* npobj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result)
1902 : {
1903 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
1904 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
1905 0 : if (id->throwOnNextInvoke) {
1906 0 : id->throwOnNextInvoke = false;
1907 0 : if (argCount == 0) {
1908 0 : NPN_SetException(npobj, NULL);
1909 : }
1910 : else {
1911 0 : for (uint32_t i = 0; i < argCount; i++) {
1912 0 : const NPString* argstr = &NPVARIANT_TO_STRING(args[i]);
1913 0 : NPN_SetException(npobj, argstr->UTF8Characters);
1914 : }
1915 : }
1916 0 : return false;
1917 : }
1918 :
1919 0 : for (int i = 0; i < int(ARRAY_LENGTH(sPluginMethodIdentifiers)); i++) {
1920 0 : if (name == sPluginMethodIdentifiers[i])
1921 0 : return sPluginMethodFunctions[i](npobj, args, argCount, result);
1922 : }
1923 0 : return false;
1924 : }
1925 :
1926 : bool
1927 0 : scriptableInvokeDefault(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
1928 : {
1929 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
1930 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
1931 0 : if (id->throwOnNextInvoke) {
1932 0 : id->throwOnNextInvoke = false;
1933 0 : if (argCount == 0) {
1934 0 : NPN_SetException(npobj, NULL);
1935 : }
1936 : else {
1937 0 : for (uint32_t i = 0; i < argCount; i++) {
1938 0 : const NPString* argstr = &NPVARIANT_TO_STRING(args[i]);
1939 0 : NPN_SetException(npobj, argstr->UTF8Characters);
1940 : }
1941 : }
1942 0 : return false;
1943 : }
1944 :
1945 0 : ostringstream value;
1946 0 : value << PLUGIN_NAME;
1947 0 : for (uint32_t i = 0; i < argCount; i++) {
1948 0 : switch(args[i].type) {
1949 : case NPVariantType_Int32:
1950 0 : value << ";" << NPVARIANT_TO_INT32(args[i]);
1951 0 : break;
1952 : case NPVariantType_String: {
1953 0 : const NPString* argstr = &NPVARIANT_TO_STRING(args[i]);
1954 0 : value << ";" << argstr->UTF8Characters;
1955 0 : break;
1956 : }
1957 : case NPVariantType_Void:
1958 0 : value << ";undefined";
1959 0 : break;
1960 : case NPVariantType_Null:
1961 0 : value << ";null";
1962 0 : break;
1963 : default:
1964 0 : value << ";other";
1965 : }
1966 : }
1967 0 : STRINGZ_TO_NPVARIANT(NPN_StrDup(value.str().c_str()), *result);
1968 0 : return true;
1969 : }
1970 :
1971 : bool
1972 0 : scriptableHasProperty(NPObject* npobj, NPIdentifier name)
1973 : {
1974 0 : if (NPN_IdentifierIsString(name)) {
1975 0 : if (NPN_GetStringIdentifier(NPN_UTF8FromIdentifier(name)) != name)
1976 0 : Crash();
1977 : }
1978 : else {
1979 0 : if (NPN_GetIntIdentifier(NPN_IntFromIdentifier(name)) != name)
1980 0 : Crash();
1981 : }
1982 0 : for (int i = 0; i < int(ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) {
1983 0 : if (name == sPluginPropertyIdentifiers[i])
1984 0 : return true;
1985 : }
1986 0 : return false;
1987 : }
1988 :
1989 : bool
1990 0 : scriptableGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result)
1991 : {
1992 0 : for (int i = 0; i < int(ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) {
1993 0 : if (name == sPluginPropertyIdentifiers[i]) {
1994 0 : DuplicateNPVariant(*result, sPluginPropertyValues[i]);
1995 0 : return true;
1996 : }
1997 : }
1998 0 : return false;
1999 : }
2000 :
2001 : bool
2002 0 : scriptableSetProperty(NPObject* npobj, NPIdentifier name, const NPVariant* value)
2003 : {
2004 0 : for (int i = 0; i < int(ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) {
2005 0 : if (name == sPluginPropertyIdentifiers[i]) {
2006 0 : NPN_ReleaseVariantValue(&sPluginPropertyValues[i]);
2007 0 : DuplicateNPVariant(sPluginPropertyValues[i], *value);
2008 0 : return true;
2009 : }
2010 : }
2011 0 : return false;
2012 : }
2013 :
2014 : bool
2015 0 : scriptableRemoveProperty(NPObject* npobj, NPIdentifier name)
2016 : {
2017 0 : for (int i = 0; i < int(ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) {
2018 0 : if (name == sPluginPropertyIdentifiers[i]) {
2019 0 : NPN_ReleaseVariantValue(&sPluginPropertyValues[i]);
2020 0 : return true;
2021 : }
2022 : }
2023 0 : return false;
2024 : }
2025 :
2026 : bool
2027 0 : scriptableEnumerate(NPObject* npobj, NPIdentifier** identifier, uint32_t* count)
2028 : {
2029 0 : const int bufsize = sizeof(NPIdentifier) * ARRAY_LENGTH(sPluginMethodIdentifierNames);
2030 0 : NPIdentifier* ids = (NPIdentifier*) NPN_MemAlloc(bufsize);
2031 0 : if (!ids)
2032 0 : return false;
2033 :
2034 0 : memcpy(ids, sPluginMethodIdentifiers, bufsize);
2035 0 : *identifier = ids;
2036 0 : *count = ARRAY_LENGTH(sPluginMethodIdentifierNames);
2037 0 : return true;
2038 : }
2039 :
2040 : bool
2041 0 : scriptableConstruct(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2042 : {
2043 0 : return false;
2044 : }
2045 :
2046 : //
2047 : // test functions
2048 : //
2049 :
2050 : static bool
2051 0 : compareVariants(NPP instance, const NPVariant* var1, const NPVariant* var2)
2052 : {
2053 0 : bool success = true;
2054 0 : InstanceData* id = static_cast<InstanceData*>(instance->pdata);
2055 0 : if (var1->type != var2->type) {
2056 0 : id->err << "Variant types don't match; got " << var1->type <<
2057 0 : " expected " << var2->type;
2058 0 : return false;
2059 : }
2060 :
2061 0 : switch (var1->type) {
2062 : case NPVariantType_Int32: {
2063 0 : int32_t result = NPVARIANT_TO_INT32(*var1);
2064 0 : int32_t expected = NPVARIANT_TO_INT32(*var2);
2065 0 : if (result != expected) {
2066 0 : id->err << "Variant values don't match; got " << result <<
2067 0 : " expected " << expected;
2068 0 : success = false;
2069 : }
2070 0 : break;
2071 : }
2072 : case NPVariantType_Double: {
2073 0 : double result = NPVARIANT_TO_DOUBLE(*var1);
2074 0 : double expected = NPVARIANT_TO_DOUBLE(*var2);
2075 0 : if (result != expected) {
2076 0 : id->err << "Variant values don't match (double)";
2077 0 : success = false;
2078 : }
2079 0 : break;
2080 : }
2081 : case NPVariantType_Void: {
2082 : // void values are always equivalent
2083 0 : break;
2084 : }
2085 : case NPVariantType_Null: {
2086 : // null values are always equivalent
2087 0 : break;
2088 : }
2089 : case NPVariantType_Bool: {
2090 0 : bool result = NPVARIANT_TO_BOOLEAN(*var1);
2091 0 : bool expected = NPVARIANT_TO_BOOLEAN(*var2);
2092 0 : if (result != expected) {
2093 0 : id->err << "Variant values don't match (bool)";
2094 0 : success = false;
2095 : }
2096 0 : break;
2097 : }
2098 : case NPVariantType_String: {
2099 0 : const NPString* result = &NPVARIANT_TO_STRING(*var1);
2100 0 : const NPString* expected = &NPVARIANT_TO_STRING(*var2);
2101 0 : if (strcmp(result->UTF8Characters, expected->UTF8Characters) ||
2102 0 : strlen(result->UTF8Characters) != strlen(expected->UTF8Characters)) {
2103 0 : id->err << "Variant values don't match; got " <<
2104 0 : result->UTF8Characters << " expected " <<
2105 0 : expected->UTF8Characters;
2106 0 : success = false;
2107 : }
2108 0 : break;
2109 : }
2110 : case NPVariantType_Object: {
2111 0 : uint32_t i, identifierCount = 0;
2112 : NPIdentifier* identifiers;
2113 0 : NPObject* result = NPVARIANT_TO_OBJECT(*var1);
2114 0 : NPObject* expected = NPVARIANT_TO_OBJECT(*var2);
2115 : bool enumerate_result = NPN_Enumerate(instance, expected,
2116 0 : &identifiers, &identifierCount);
2117 0 : if (!enumerate_result) {
2118 0 : id->err << "NPN_Enumerate failed";
2119 0 : success = false;
2120 : }
2121 0 : for (i = 0; i < identifierCount; i++) {
2122 : NPVariant resultVariant, expectedVariant;
2123 0 : if (!NPN_GetProperty(instance, expected, identifiers[i],
2124 0 : &expectedVariant)) {
2125 0 : id->err << "NPN_GetProperty returned false";
2126 0 : success = false;
2127 : }
2128 : else {
2129 0 : if (!NPN_HasProperty(instance, result, identifiers[i])) {
2130 0 : id->err << "NPN_HasProperty returned false";
2131 0 : success = false;
2132 : }
2133 : else {
2134 0 : if (!NPN_GetProperty(instance, result, identifiers[i],
2135 0 : &resultVariant)) {
2136 0 : id->err << "NPN_GetProperty 2 returned false";
2137 0 : success = false;
2138 : }
2139 : else {
2140 : success = compareVariants(instance, &resultVariant,
2141 0 : &expectedVariant);
2142 0 : NPN_ReleaseVariantValue(&expectedVariant);
2143 : }
2144 : }
2145 0 : NPN_ReleaseVariantValue(&resultVariant);
2146 : }
2147 : }
2148 0 : break;
2149 : }
2150 : default:
2151 0 : id->err << "Unknown variant type";
2152 0 : success = false;
2153 : }
2154 :
2155 0 : return success;
2156 : }
2157 :
2158 : static bool
2159 0 : throwExceptionNextInvoke(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2160 : {
2161 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2162 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
2163 0 : id->throwOnNextInvoke = true;
2164 0 : BOOLEAN_TO_NPVARIANT(true, *result);
2165 0 : return true;
2166 : }
2167 :
2168 : static bool
2169 0 : npnInvokeDefaultTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2170 : {
2171 0 : bool success = false;
2172 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2173 :
2174 : NPObject* windowObject;
2175 0 : NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
2176 0 : if (!windowObject)
2177 0 : return false;
2178 :
2179 0 : NPIdentifier objectIdentifier = variantToIdentifier(args[0]);
2180 0 : if (!objectIdentifier)
2181 0 : return false;
2182 :
2183 : NPVariant objectVariant;
2184 0 : if (NPN_GetProperty(npp, windowObject, objectIdentifier,
2185 0 : &objectVariant)) {
2186 0 : if (NPVARIANT_IS_OBJECT(objectVariant)) {
2187 0 : NPObject* selfObject = NPVARIANT_TO_OBJECT(objectVariant);
2188 0 : if (selfObject != NULL) {
2189 : NPVariant resultVariant;
2190 0 : if (NPN_InvokeDefault(npp, selfObject, argCount > 1 ? &args[1] : NULL,
2191 0 : argCount - 1, &resultVariant)) {
2192 0 : *result = resultVariant;
2193 0 : success = true;
2194 : }
2195 : }
2196 : }
2197 0 : NPN_ReleaseVariantValue(&objectVariant);
2198 : }
2199 :
2200 0 : NPN_ReleaseObject(windowObject);
2201 0 : return success;
2202 : }
2203 :
2204 : static bool
2205 0 : npnInvokeTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2206 : {
2207 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2208 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
2209 0 : id->err.str("");
2210 0 : if (argCount < 2)
2211 0 : return false;
2212 :
2213 0 : NPIdentifier function = variantToIdentifier(args[0]);
2214 0 : if (!function)
2215 0 : return false;
2216 :
2217 : NPObject* windowObject;
2218 0 : NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
2219 0 : if (!windowObject)
2220 0 : return false;
2221 :
2222 : NPVariant invokeResult;
2223 : bool invokeReturn = NPN_Invoke(npp, windowObject, function,
2224 0 : argCount > 2 ? &args[2] : NULL, argCount - 2, &invokeResult);
2225 :
2226 0 : bool compareResult = compareVariants(npp, &invokeResult, &args[1]);
2227 :
2228 0 : NPN_ReleaseObject(windowObject);
2229 0 : NPN_ReleaseVariantValue(&invokeResult);
2230 0 : BOOLEAN_TO_NPVARIANT(invokeReturn && compareResult, *result);
2231 0 : return true;
2232 : }
2233 :
2234 : static bool
2235 0 : npnEvaluateTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2236 : {
2237 0 : bool success = false;
2238 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2239 :
2240 0 : if (argCount != 1)
2241 0 : return false;
2242 :
2243 0 : if (!NPVARIANT_IS_STRING(args[0]))
2244 0 : return false;
2245 :
2246 : NPObject* windowObject;
2247 0 : NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
2248 0 : if (!windowObject)
2249 0 : return false;
2250 :
2251 0 : success = NPN_Evaluate(npp, windowObject, (NPString*)&NPVARIANT_TO_STRING(args[0]), result);
2252 :
2253 0 : NPN_ReleaseObject(windowObject);
2254 0 : return success;
2255 : }
2256 :
2257 : static bool
2258 0 : setUndefinedValueTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2259 : {
2260 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2261 0 : NPError err = NPN_SetValue(npp, (NPPVariable)0x0, 0x0);
2262 0 : BOOLEAN_TO_NPVARIANT((err == NPERR_NO_ERROR), *result);
2263 0 : return true;
2264 : }
2265 :
2266 : static bool
2267 0 : identifierToStringTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2268 : {
2269 0 : if (argCount != 1)
2270 0 : return false;
2271 0 : NPIdentifier identifier = variantToIdentifier(args[0]);
2272 0 : if (!identifier)
2273 0 : return false;
2274 :
2275 0 : NPUTF8* utf8String = NPN_UTF8FromIdentifier(identifier);
2276 0 : if (!utf8String)
2277 0 : return false;
2278 0 : STRINGZ_TO_NPVARIANT(utf8String, *result);
2279 0 : return true;
2280 : }
2281 :
2282 : static bool
2283 0 : queryPrivateModeState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2284 : {
2285 0 : if (argCount != 0)
2286 0 : return false;
2287 :
2288 0 : NPBool pms = false;
2289 0 : NPN_GetValue(static_cast<TestNPObject*>(npobj)->npp, NPNVprivateModeBool, &pms);
2290 0 : BOOLEAN_TO_NPVARIANT(pms, *result);
2291 0 : return true;
2292 : }
2293 :
2294 : static bool
2295 0 : lastReportedPrivateModeState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2296 : {
2297 0 : if (argCount != 0)
2298 0 : return false;
2299 :
2300 0 : InstanceData* id = static_cast<InstanceData*>(static_cast<TestNPObject*>(npobj)->npp->pdata);
2301 0 : BOOLEAN_TO_NPVARIANT(id->lastReportedPrivateModeState, *result);
2302 0 : return true;
2303 : }
2304 :
2305 : static bool
2306 0 : hasWidget(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2307 : {
2308 0 : if (argCount != 0)
2309 0 : return false;
2310 :
2311 0 : InstanceData* id = static_cast<InstanceData*>(static_cast<TestNPObject*>(npobj)->npp->pdata);
2312 0 : BOOLEAN_TO_NPVARIANT(id->hasWidget, *result);
2313 0 : return true;
2314 : }
2315 :
2316 : static bool
2317 0 : getEdge(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2318 : {
2319 0 : if (argCount != 1)
2320 0 : return false;
2321 0 : if (!NPVARIANT_IS_INT32(args[0]))
2322 0 : return false;
2323 0 : int32_t edge = NPVARIANT_TO_INT32(args[0]);
2324 0 : if (edge < EDGE_LEFT || edge > EDGE_BOTTOM)
2325 0 : return false;
2326 :
2327 0 : InstanceData* id = static_cast<InstanceData*>(static_cast<TestNPObject*>(npobj)->npp->pdata);
2328 0 : int32_t r = pluginGetEdge(id, RectEdge(edge));
2329 0 : if (r == NPTEST_INT32_ERROR)
2330 0 : return false;
2331 0 : INT32_TO_NPVARIANT(r, *result);
2332 0 : return true;
2333 : }
2334 :
2335 : static bool
2336 0 : getClipRegionRectCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2337 : {
2338 0 : if (argCount != 0)
2339 0 : return false;
2340 :
2341 0 : InstanceData* id = static_cast<InstanceData*>(static_cast<TestNPObject*>(npobj)->npp->pdata);
2342 0 : int32_t r = pluginGetClipRegionRectCount(id);
2343 0 : if (r == NPTEST_INT32_ERROR)
2344 0 : return false;
2345 0 : INT32_TO_NPVARIANT(r, *result);
2346 0 : return true;
2347 : }
2348 :
2349 : static bool
2350 0 : getClipRegionRectEdge(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2351 : {
2352 0 : if (argCount != 2)
2353 0 : return false;
2354 0 : if (!NPVARIANT_IS_INT32(args[0]))
2355 0 : return false;
2356 0 : int32_t rectIndex = NPVARIANT_TO_INT32(args[0]);
2357 0 : if (rectIndex < 0)
2358 0 : return false;
2359 0 : if (!NPVARIANT_IS_INT32(args[1]))
2360 0 : return false;
2361 0 : int32_t edge = NPVARIANT_TO_INT32(args[1]);
2362 0 : if (edge < EDGE_LEFT || edge > EDGE_BOTTOM)
2363 0 : return false;
2364 :
2365 0 : InstanceData* id = static_cast<InstanceData*>(static_cast<TestNPObject*>(npobj)->npp->pdata);
2366 0 : int32_t r = pluginGetClipRegionRectEdge(id, rectIndex, RectEdge(edge));
2367 0 : if (r == NPTEST_INT32_ERROR)
2368 0 : return false;
2369 0 : INT32_TO_NPVARIANT(r, *result);
2370 0 : return true;
2371 : }
2372 :
2373 : static bool
2374 0 : startWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2375 : {
2376 0 : if (argCount != 0)
2377 0 : return false;
2378 0 : if (sWatchingInstanceCount)
2379 0 : return false;
2380 :
2381 0 : sWatchingInstanceCount = true;
2382 0 : sInstanceCount = 0;
2383 0 : ++sCurrentInstanceCountWatchGeneration;
2384 0 : return true;
2385 : }
2386 :
2387 : static bool
2388 0 : getInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2389 : {
2390 0 : if (argCount != 0)
2391 0 : return false;
2392 0 : if (!sWatchingInstanceCount)
2393 0 : return false;
2394 :
2395 0 : INT32_TO_NPVARIANT(sInstanceCount, *result);
2396 0 : return true;
2397 : }
2398 :
2399 : static bool
2400 0 : stopWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2401 : {
2402 0 : if (argCount != 0)
2403 0 : return false;
2404 0 : if (!sWatchingInstanceCount)
2405 0 : return false;
2406 :
2407 0 : sWatchingInstanceCount = false;
2408 0 : return true;
2409 : }
2410 :
2411 : static bool
2412 0 : getLastMouseX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2413 : {
2414 0 : if (argCount != 0)
2415 0 : return false;
2416 :
2417 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2418 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
2419 0 : INT32_TO_NPVARIANT(id->lastMouseX, *result);
2420 0 : return true;
2421 : }
2422 :
2423 : static bool
2424 0 : getLastMouseY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2425 : {
2426 0 : if (argCount != 0)
2427 0 : return false;
2428 :
2429 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2430 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
2431 0 : INT32_TO_NPVARIANT(id->lastMouseY, *result);
2432 0 : return true;
2433 : }
2434 :
2435 : static bool
2436 0 : getPaintCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2437 : {
2438 0 : if (argCount != 0)
2439 0 : return false;
2440 :
2441 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2442 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
2443 0 : INT32_TO_NPVARIANT(id->paintCount, *result);
2444 0 : return true;
2445 : }
2446 :
2447 : static bool
2448 0 : getWidthAtLastPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2449 : {
2450 0 : if (argCount != 0)
2451 0 : return false;
2452 :
2453 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2454 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
2455 0 : INT32_TO_NPVARIANT(id->widthAtLastPaint, *result);
2456 0 : return true;
2457 : }
2458 :
2459 : static bool
2460 0 : setInvalidateDuringPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2461 : {
2462 0 : if (argCount != 1)
2463 0 : return false;
2464 :
2465 0 : if (!NPVARIANT_IS_BOOLEAN(args[0]))
2466 0 : return false;
2467 0 : bool doInvalidate = NPVARIANT_TO_BOOLEAN(args[0]);
2468 :
2469 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2470 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
2471 0 : id->invalidateDuringPaint = doInvalidate;
2472 0 : return true;
2473 : }
2474 :
2475 : static bool
2476 0 : getError(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2477 : {
2478 0 : if (argCount != 0)
2479 0 : return false;
2480 :
2481 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2482 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
2483 0 : if (id->err.str().length() == 0)
2484 0 : STRINGZ_TO_NPVARIANT(NPN_StrDup(SUCCESS_STRING), *result);
2485 : else
2486 0 : STRINGZ_TO_NPVARIANT(NPN_StrDup(id->err.str().c_str()), *result);
2487 0 : return true;
2488 : }
2489 :
2490 : static bool
2491 0 : doInternalConsistencyCheck(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2492 : {
2493 0 : if (argCount != 0)
2494 0 : return false;
2495 :
2496 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2497 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
2498 0 : string error;
2499 0 : pluginDoInternalConsistencyCheck(id, error);
2500 0 : NPUTF8* utf8String = (NPUTF8*)NPN_MemAlloc(error.length() + 1);
2501 0 : if (!utf8String) {
2502 0 : return false;
2503 : }
2504 0 : memcpy(utf8String, error.c_str(), error.length() + 1);
2505 0 : STRINGZ_TO_NPVARIANT(utf8String, *result);
2506 0 : return true;
2507 : }
2508 :
2509 : static bool
2510 0 : convertPointX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2511 : {
2512 0 : if (argCount != 4)
2513 0 : return false;
2514 :
2515 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2516 :
2517 0 : if (!NPVARIANT_IS_INT32(args[0]))
2518 0 : return false;
2519 0 : int32_t sourceSpace = NPVARIANT_TO_INT32(args[0]);
2520 :
2521 0 : if (!NPVARIANT_IS_INT32(args[1]))
2522 0 : return false;
2523 0 : double sourceX = static_cast<double>(NPVARIANT_TO_INT32(args[1]));
2524 :
2525 0 : if (!NPVARIANT_IS_INT32(args[2]))
2526 0 : return false;
2527 0 : double sourceY = static_cast<double>(NPVARIANT_TO_INT32(args[2]));
2528 :
2529 0 : if (!NPVARIANT_IS_INT32(args[3]))
2530 0 : return false;
2531 0 : int32_t destSpace = NPVARIANT_TO_INT32(args[3]);
2532 :
2533 : double resultX, resultY;
2534 0 : NPN_ConvertPoint(npp, sourceX, sourceY, (NPCoordinateSpace)sourceSpace, &resultX, &resultY, (NPCoordinateSpace)destSpace);
2535 :
2536 0 : DOUBLE_TO_NPVARIANT(resultX, *result);
2537 0 : return true;
2538 : }
2539 :
2540 : static bool
2541 0 : convertPointY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2542 : {
2543 0 : if (argCount != 4)
2544 0 : return false;
2545 :
2546 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2547 :
2548 0 : if (!NPVARIANT_IS_INT32(args[0]))
2549 0 : return false;
2550 0 : int32_t sourceSpace = NPVARIANT_TO_INT32(args[0]);
2551 :
2552 0 : if (!NPVARIANT_IS_INT32(args[1]))
2553 0 : return false;
2554 0 : double sourceX = static_cast<double>(NPVARIANT_TO_INT32(args[1]));
2555 :
2556 0 : if (!NPVARIANT_IS_INT32(args[2]))
2557 0 : return false;
2558 0 : double sourceY = static_cast<double>(NPVARIANT_TO_INT32(args[2]));
2559 :
2560 0 : if (!NPVARIANT_IS_INT32(args[3]))
2561 0 : return false;
2562 0 : int32_t destSpace = NPVARIANT_TO_INT32(args[3]);
2563 :
2564 : double resultX, resultY;
2565 0 : NPN_ConvertPoint(npp, sourceX, sourceY, (NPCoordinateSpace)sourceSpace, &resultX, &resultY, (NPCoordinateSpace)destSpace);
2566 :
2567 0 : DOUBLE_TO_NPVARIANT(resultY, *result);
2568 0 : return true;
2569 : }
2570 :
2571 : static bool
2572 0 : streamTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2573 : {
2574 : // .streamTest(url, doPost, doNull, writeCallback, notifyCallback, redirectCallback, allowRedirects)
2575 0 : if (7 != argCount)
2576 0 : return false;
2577 :
2578 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2579 :
2580 0 : if (!NPVARIANT_IS_STRING(args[0]))
2581 0 : return false;
2582 0 : NPString url = NPVARIANT_TO_STRING(args[0]);
2583 :
2584 0 : if (!NPVARIANT_IS_BOOLEAN(args[1]))
2585 0 : return false;
2586 0 : bool doPost = NPVARIANT_TO_BOOLEAN(args[1]);
2587 :
2588 0 : NPString postData = { NULL, 0 };
2589 0 : if (NPVARIANT_IS_STRING(args[2])) {
2590 0 : postData = NPVARIANT_TO_STRING(args[2]);
2591 : }
2592 : else {
2593 0 : if (!NPVARIANT_IS_NULL(args[2])) {
2594 0 : return false;
2595 : }
2596 : }
2597 :
2598 0 : NPObject* writeCallback = NULL;
2599 0 : if (NPVARIANT_IS_OBJECT(args[3])) {
2600 0 : writeCallback = NPVARIANT_TO_OBJECT(args[3]);
2601 : }
2602 : else {
2603 0 : if (!NPVARIANT_IS_NULL(args[3])) {
2604 0 : return false;
2605 : }
2606 : }
2607 :
2608 0 : NPObject* notifyCallback = NULL;
2609 0 : if (NPVARIANT_IS_OBJECT(args[4])) {
2610 0 : notifyCallback = NPVARIANT_TO_OBJECT(args[4]);
2611 : }
2612 : else {
2613 0 : if (!NPVARIANT_IS_NULL(args[4])) {
2614 0 : return false;
2615 : }
2616 : }
2617 :
2618 0 : NPObject* redirectCallback = NULL;
2619 0 : if (NPVARIANT_IS_OBJECT(args[5])) {
2620 0 : redirectCallback = NPVARIANT_TO_OBJECT(args[5]);
2621 : }
2622 : else {
2623 0 : if (!NPVARIANT_IS_NULL(args[5])) {
2624 0 : return false;
2625 : }
2626 : }
2627 :
2628 0 : if (!NPVARIANT_IS_BOOLEAN(args[6]))
2629 0 : return false;
2630 0 : bool allowRedirects = NPVARIANT_TO_BOOLEAN(args[6]);
2631 :
2632 0 : URLNotifyData* ndata = new URLNotifyData;
2633 0 : ndata->cookie = "dynamic-cookie";
2634 0 : ndata->writeCallback = writeCallback;
2635 0 : ndata->notifyCallback = notifyCallback;
2636 0 : ndata->redirectCallback = redirectCallback;
2637 0 : ndata->size = 0;
2638 0 : ndata->data = NULL;
2639 0 : ndata->allowRedirects = allowRedirects;
2640 :
2641 : /* null-terminate "url" */
2642 0 : char* urlstr = (char*) malloc(url.UTF8Length + 1);
2643 0 : strncpy(urlstr, url.UTF8Characters, url.UTF8Length);
2644 0 : urlstr[url.UTF8Length] = '\0';
2645 :
2646 : NPError err;
2647 0 : if (doPost) {
2648 : err = NPN_PostURLNotify(npp, urlstr, NULL,
2649 : postData.UTF8Length, postData.UTF8Characters,
2650 0 : false, ndata);
2651 : }
2652 : else {
2653 0 : err = NPN_GetURLNotify(npp, urlstr, NULL, ndata);
2654 : }
2655 :
2656 0 : free(urlstr);
2657 :
2658 0 : if (NPERR_NO_ERROR == err) {
2659 0 : if (ndata->writeCallback) {
2660 0 : NPN_RetainObject(ndata->writeCallback);
2661 : }
2662 0 : if (ndata->notifyCallback) {
2663 0 : NPN_RetainObject(ndata->notifyCallback);
2664 : }
2665 0 : if (ndata->redirectCallback) {
2666 0 : NPN_RetainObject(ndata->redirectCallback);
2667 : }
2668 0 : BOOLEAN_TO_NPVARIANT(true, *result);
2669 : }
2670 : else {
2671 0 : delete ndata;
2672 0 : BOOLEAN_TO_NPVARIANT(false, *result);
2673 : }
2674 :
2675 0 : return true;
2676 : }
2677 :
2678 : static bool
2679 0 : setPluginWantsAllStreams(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2680 : {
2681 0 : if (1 != argCount)
2682 0 : return false;
2683 :
2684 0 : if (!NPVARIANT_IS_BOOLEAN(args[0]))
2685 0 : return false;
2686 0 : bool wantsAllStreams = NPVARIANT_TO_BOOLEAN(args[0]);
2687 :
2688 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2689 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
2690 :
2691 0 : id->wantsAllStreams = wantsAllStreams;
2692 :
2693 0 : return true;
2694 : }
2695 :
2696 : static bool
2697 0 : crashPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2698 : {
2699 0 : IntentionalCrash();
2700 0 : VOID_TO_NPVARIANT(*result);
2701 0 : return true;
2702 : }
2703 :
2704 : static bool
2705 0 : crashOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2706 : {
2707 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2708 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
2709 :
2710 0 : id->crashOnDestroy = true;
2711 0 : VOID_TO_NPVARIANT(*result);
2712 0 : return true;
2713 : }
2714 :
2715 : static bool
2716 0 : setColor(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2717 : {
2718 0 : if (argCount != 1)
2719 0 : return false;
2720 0 : if (!NPVARIANT_IS_STRING(args[0]))
2721 0 : return false;
2722 0 : const NPString* str = &NPVARIANT_TO_STRING(args[0]);
2723 :
2724 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2725 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
2726 :
2727 : id->scriptableObject->drawColor =
2728 0 : parseHexColor(str->UTF8Characters, str->UTF8Length);
2729 :
2730 : NPRect r;
2731 0 : r.left = 0;
2732 0 : r.top = 0;
2733 0 : r.right = id->window.width;
2734 0 : r.bottom = id->window.height;
2735 0 : if (id->asyncDrawing == AD_NONE) {
2736 0 : NPN_InvalidateRect(npp, &r);
2737 0 : } else if (id->asyncDrawing == AD_BITMAP) {
2738 0 : drawAsyncBitmapColor(id);
2739 : }
2740 :
2741 0 : VOID_TO_NPVARIANT(*result);
2742 0 : return true;
2743 : }
2744 :
2745 0 : void notifyDidPaint(InstanceData* instanceData)
2746 : {
2747 0 : ++instanceData->paintCount;
2748 0 : instanceData->widthAtLastPaint = instanceData->window.width;
2749 :
2750 0 : if (instanceData->invalidateDuringPaint) {
2751 : NPRect r;
2752 0 : r.left = 0;
2753 0 : r.top = 0;
2754 0 : r.right = instanceData->window.width;
2755 0 : r.bottom = instanceData->window.height;
2756 0 : NPN_InvalidateRect(instanceData->npp, &r);
2757 : }
2758 :
2759 0 : if (instanceData->runScriptOnPaint) {
2760 0 : NPObject* o = NULL;
2761 0 : NPN_GetValue(instanceData->npp, NPNVPluginElementNPObject, &o);
2762 0 : if (o) {
2763 : NPVariant param;
2764 0 : STRINGZ_TO_NPVARIANT("paintscript", param);
2765 : NPVariant result;
2766 : NPN_Invoke(instanceData->npp, o, NPN_GetStringIdentifier("getAttribute"),
2767 0 : ¶m, 1, &result);
2768 :
2769 0 : if (NPVARIANT_IS_STRING(result)) {
2770 : NPObject* windowObject;
2771 0 : NPN_GetValue(instanceData->npp, NPNVWindowNPObject, &windowObject);
2772 0 : if (windowObject) {
2773 : NPVariant evalResult;
2774 : NPN_Evaluate(instanceData->npp, windowObject,
2775 0 : (NPString*)&NPVARIANT_TO_STRING(result), &evalResult);
2776 0 : NPN_ReleaseVariantValue(&evalResult);
2777 0 : NPN_ReleaseObject(windowObject);
2778 : }
2779 : }
2780 :
2781 0 : NPN_ReleaseVariantValue(&result);
2782 0 : NPN_ReleaseObject(o);
2783 : }
2784 : }
2785 0 : }
2786 :
2787 : static const NPClass kTestSharedNPClass = {
2788 : NP_CLASS_STRUCT_VERSION,
2789 : // Everything else is NULL
2790 : };
2791 :
2792 0 : static bool getObjectValue(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2793 : {
2794 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2795 :
2796 : NPObject* o = NPN_CreateObject(npp,
2797 0 : const_cast<NPClass*>(&kTestSharedNPClass));
2798 0 : if (!o)
2799 0 : return false;
2800 :
2801 0 : OBJECT_TO_NPVARIANT(o, *result);
2802 0 : return true;
2803 : }
2804 :
2805 0 : static bool checkObjectValue(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2806 : {
2807 0 : VOID_TO_NPVARIANT(*result);
2808 :
2809 0 : if (1 != argCount)
2810 0 : return false;
2811 :
2812 0 : if (!NPVARIANT_IS_OBJECT(args[0]))
2813 0 : return false;
2814 :
2815 0 : NPObject* o = NPVARIANT_TO_OBJECT(args[0]);
2816 :
2817 0 : BOOLEAN_TO_NPVARIANT(o->_class == &kTestSharedNPClass, *result);
2818 0 : return true;
2819 : }
2820 :
2821 0 : static bool enableFPExceptions(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2822 : {
2823 0 : VOID_TO_NPVARIANT(*result);
2824 :
2825 : #if defined(XP_WIN) && defined(_M_IX86)
2826 : _control87(0, _MCW_EM);
2827 : return true;
2828 : #else
2829 0 : return false;
2830 : #endif
2831 : }
2832 :
2833 : // caller is responsible for freeing return buffer
2834 0 : static char* URLForInstanceWindow(NPP instance) {
2835 0 : char *outString = NULL;
2836 :
2837 0 : NPObject* windowObject = NULL;
2838 0 : NPError err = NPN_GetValue(instance, NPNVWindowNPObject, &windowObject);
2839 0 : if (err != NPERR_NO_ERROR || !windowObject)
2840 0 : return NULL;
2841 :
2842 0 : NPIdentifier locationIdentifier = NPN_GetStringIdentifier("location");
2843 : NPVariant locationVariant;
2844 0 : if (NPN_GetProperty(instance, windowObject, locationIdentifier, &locationVariant)) {
2845 0 : NPObject *locationObject = locationVariant.value.objectValue;
2846 0 : if (locationObject) {
2847 0 : NPIdentifier hrefIdentifier = NPN_GetStringIdentifier("href");
2848 : NPVariant hrefVariant;
2849 0 : if (NPN_GetProperty(instance, locationObject, hrefIdentifier, &hrefVariant)) {
2850 0 : const NPString* hrefString = &NPVARIANT_TO_STRING(hrefVariant);
2851 0 : if (hrefString) {
2852 0 : outString = (char *)malloc(hrefString->UTF8Length + 1);
2853 0 : if (outString) {
2854 0 : strcpy(outString, hrefString->UTF8Characters);
2855 0 : outString[hrefString->UTF8Length] = '\0';
2856 : }
2857 : }
2858 0 : NPN_ReleaseVariantValue(&hrefVariant);
2859 : }
2860 : }
2861 0 : NPN_ReleaseVariantValue(&locationVariant);
2862 : }
2863 :
2864 0 : NPN_ReleaseObject(windowObject);
2865 :
2866 0 : return outString;
2867 : }
2868 :
2869 : static bool
2870 0 : setCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2871 : {
2872 0 : if (argCount != 1)
2873 0 : return false;
2874 0 : if (!NPVARIANT_IS_STRING(args[0]))
2875 0 : return false;
2876 0 : const NPString* cookie = &NPVARIANT_TO_STRING(args[0]);
2877 :
2878 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2879 :
2880 0 : char* url = URLForInstanceWindow(npp);
2881 0 : if (!url)
2882 0 : return false;
2883 0 : NPError err = NPN_SetValueForURL(npp, NPNURLVCookie, url, cookie->UTF8Characters, cookie->UTF8Length);
2884 0 : free(url);
2885 :
2886 0 : return (err == NPERR_NO_ERROR);
2887 : }
2888 :
2889 : static bool
2890 0 : getCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2891 : {
2892 0 : if (argCount != 0)
2893 0 : return false;
2894 :
2895 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2896 :
2897 0 : char* url = URLForInstanceWindow(npp);
2898 0 : if (!url)
2899 0 : return false;
2900 0 : char* cookie = NULL;
2901 0 : unsigned int length = 0;
2902 0 : NPError err = NPN_GetValueForURL(npp, NPNURLVCookie, url, &cookie, &length);
2903 0 : free(url);
2904 0 : if (err != NPERR_NO_ERROR || !cookie)
2905 0 : return false;
2906 :
2907 0 : STRINGZ_TO_NPVARIANT(cookie, *result);
2908 0 : return true;
2909 : }
2910 :
2911 : static bool
2912 0 : getAuthInfo(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2913 : {
2914 0 : if (argCount != 5)
2915 0 : return false;
2916 :
2917 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
2918 :
2919 0 : if (!NPVARIANT_IS_STRING(args[0]) || !NPVARIANT_IS_STRING(args[1]) ||
2920 0 : !NPVARIANT_IS_INT32(args[2]) || !NPVARIANT_IS_STRING(args[3]) ||
2921 0 : !NPVARIANT_IS_STRING(args[4]))
2922 0 : return false;
2923 :
2924 0 : const NPString* protocol = &NPVARIANT_TO_STRING(args[0]);
2925 0 : const NPString* host = &NPVARIANT_TO_STRING(args[1]);
2926 0 : uint32_t port = NPVARIANT_TO_INT32(args[2]);
2927 0 : const NPString* scheme = &NPVARIANT_TO_STRING(args[3]);
2928 0 : const NPString* realm = &NPVARIANT_TO_STRING(args[4]);
2929 :
2930 0 : char* username = NULL;
2931 0 : char* password = NULL;
2932 0 : uint32_t ulen = 0, plen = 0;
2933 :
2934 : NPError err = NPN_GetAuthenticationInfo(npp,
2935 : protocol->UTF8Characters,
2936 : host->UTF8Characters,
2937 : port,
2938 : scheme->UTF8Characters,
2939 : realm->UTF8Characters,
2940 : &username,
2941 : &ulen,
2942 : &password,
2943 0 : &plen);
2944 :
2945 0 : if (err != NPERR_NO_ERROR) {
2946 0 : return false;
2947 : }
2948 :
2949 0 : char* outstring = (char*)NPN_MemAlloc(ulen + plen + 2);
2950 0 : memset(outstring, 0, ulen + plen + 2);
2951 0 : strncpy(outstring, username, ulen);
2952 0 : strcat(outstring, "|");
2953 0 : strncat(outstring, password, plen);
2954 :
2955 0 : STRINGZ_TO_NPVARIANT(outstring, *result);
2956 :
2957 0 : NPN_MemFree(username);
2958 0 : NPN_MemFree(password);
2959 :
2960 0 : return true;
2961 : }
2962 :
2963 0 : static void timerCallback(NPP npp, uint32_t timerID)
2964 : {
2965 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
2966 0 : currentTimerEventCount++;
2967 0 : timerEvent event = timerEvents[currentTimerEventCount];
2968 :
2969 : NPObject* windowObject;
2970 0 : NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
2971 0 : if (!windowObject)
2972 0 : return;
2973 :
2974 : NPVariant rval;
2975 0 : if (timerID != id->timerID[event.timerIdReceive]) {
2976 0 : id->timerTestResult = false;
2977 : }
2978 :
2979 0 : if (currentTimerEventCount == totalTimerEvents - 1) {
2980 : NPVariant arg;
2981 0 : BOOLEAN_TO_NPVARIANT(id->timerTestResult, arg);
2982 0 : NPN_Invoke(npp, windowObject, NPN_GetStringIdentifier(id->timerTestScriptCallback.c_str()), &arg, 1, &rval);
2983 0 : NPN_ReleaseVariantValue(&arg);
2984 : }
2985 :
2986 0 : NPN_ReleaseObject(windowObject);
2987 :
2988 0 : if (event.timerIdSchedule > -1) {
2989 0 : id->timerID[event.timerIdSchedule] = NPN_ScheduleTimer(npp, event.timerInterval, event.timerRepeat, timerCallback);
2990 : }
2991 0 : if (event.timerIdUnschedule > -1) {
2992 0 : NPN_UnscheduleTimer(npp, id->timerID[event.timerIdUnschedule]);
2993 : }
2994 : }
2995 :
2996 : static bool
2997 0 : timerTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
2998 : {
2999 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3000 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3001 0 : currentTimerEventCount = 0;
3002 :
3003 0 : if (argCount < 1 || !NPVARIANT_IS_STRING(args[0]))
3004 0 : return false;
3005 0 : const NPString* argstr = &NPVARIANT_TO_STRING(args[0]);
3006 0 : id->timerTestScriptCallback = argstr->UTF8Characters;
3007 :
3008 0 : id->timerTestResult = true;
3009 0 : timerEvent event = timerEvents[currentTimerEventCount];
3010 :
3011 0 : id->timerID[event.timerIdSchedule] = NPN_ScheduleTimer(npp, event.timerInterval, event.timerRepeat, timerCallback);
3012 :
3013 0 : return id->timerID[event.timerIdSchedule] != 0;
3014 : }
3015 :
3016 : #ifdef XP_WIN
3017 : void
3018 : ThreadProc(void* cookie)
3019 : #else
3020 : void*
3021 0 : ThreadProc(void* cookie)
3022 : #endif
3023 : {
3024 0 : NPObject* npobj = (NPObject*)cookie;
3025 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3026 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3027 0 : id->asyncTestPhase = 1;
3028 0 : NPN_PluginThreadAsyncCall(npp, asyncCallback, (void*)npobj);
3029 : #ifndef XP_WIN
3030 0 : return NULL;
3031 : #endif
3032 : }
3033 :
3034 : void
3035 0 : asyncCallback(void* cookie)
3036 : {
3037 0 : NPObject* npobj = (NPObject*)cookie;
3038 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3039 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3040 :
3041 0 : switch (id->asyncTestPhase) {
3042 : // async callback triggered from same thread
3043 : case 0:
3044 : #ifdef XP_WIN
3045 : if (_beginthread(ThreadProc, 0, (void*)npobj) == -1)
3046 : id->asyncCallbackResult = false;
3047 : #else
3048 : pthread_t tid;
3049 0 : if (pthread_create(&tid, 0, ThreadProc, (void*)npobj))
3050 0 : id->asyncCallbackResult = false;
3051 : #endif
3052 0 : break;
3053 :
3054 : // async callback triggered from different thread
3055 : default:
3056 : NPObject* windowObject;
3057 0 : NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
3058 0 : if (!windowObject)
3059 0 : return;
3060 : NPVariant arg, rval;
3061 0 : BOOLEAN_TO_NPVARIANT(id->asyncCallbackResult, arg);
3062 0 : NPN_Invoke(npp, windowObject, NPN_GetStringIdentifier(id->asyncTestScriptCallback.c_str()), &arg, 1, &rval);
3063 0 : NPN_ReleaseVariantValue(&arg);
3064 0 : NPN_ReleaseObject(windowObject);
3065 0 : break;
3066 : }
3067 : }
3068 :
3069 : static bool
3070 0 : asyncCallbackTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
3071 : {
3072 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3073 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3074 :
3075 0 : if (argCount < 1 || !NPVARIANT_IS_STRING(args[0]))
3076 0 : return false;
3077 0 : const NPString* argstr = &NPVARIANT_TO_STRING(args[0]);
3078 0 : id->asyncTestScriptCallback = argstr->UTF8Characters;
3079 :
3080 0 : id->asyncTestPhase = 0;
3081 0 : id->asyncCallbackResult = true;
3082 0 : NPN_PluginThreadAsyncCall(npp, asyncCallback, (void*)npobj);
3083 :
3084 0 : return true;
3085 : }
3086 :
3087 : static bool
3088 0 : GCRaceInvoke(NPObject*, NPIdentifier, const NPVariant*, uint32_t, NPVariant*)
3089 : {
3090 0 : return false;
3091 : }
3092 :
3093 : static bool
3094 0 : GCRaceInvokeDefault(NPObject* o, const NPVariant* args, uint32_t argCount,
3095 : NPVariant* result)
3096 : {
3097 0 : if (1 != argCount || !NPVARIANT_IS_INT32(args[0]) ||
3098 : 35 != NPVARIANT_TO_INT32(args[0]))
3099 0 : return false;
3100 :
3101 0 : return true;
3102 : }
3103 :
3104 : static const NPClass kGCRaceClass = {
3105 : NP_CLASS_STRUCT_VERSION,
3106 : NULL,
3107 : NULL,
3108 : NULL,
3109 : NULL,
3110 : GCRaceInvoke,
3111 : GCRaceInvokeDefault,
3112 : NULL,
3113 : NULL,
3114 : NULL,
3115 : NULL,
3116 : NULL,
3117 : NULL
3118 : };
3119 :
3120 : struct GCRaceData
3121 : {
3122 0 : GCRaceData(NPP npp, NPObject* callback, NPObject* localFunc)
3123 : : npp_(npp)
3124 : , callback_(callback)
3125 0 : , localFunc_(localFunc)
3126 : {
3127 0 : NPN_RetainObject(callback_);
3128 0 : NPN_RetainObject(localFunc_);
3129 0 : }
3130 :
3131 0 : ~GCRaceData()
3132 : {
3133 0 : NPN_ReleaseObject(callback_);
3134 0 : NPN_ReleaseObject(localFunc_);
3135 0 : }
3136 :
3137 : NPP npp_;
3138 : NPObject* callback_;
3139 : NPObject* localFunc_;
3140 : };
3141 :
3142 : static void
3143 0 : FinishGCRace(void* closure)
3144 : {
3145 0 : GCRaceData* rd = static_cast<GCRaceData*>(closure);
3146 :
3147 : #ifdef XP_WIN
3148 : Sleep(5000);
3149 : #else
3150 0 : sleep(5);
3151 : #endif
3152 :
3153 : NPVariant arg;
3154 0 : OBJECT_TO_NPVARIANT(rd->localFunc_, arg);
3155 :
3156 : NPVariant result;
3157 0 : bool ok = NPN_InvokeDefault(rd->npp_, rd->callback_, &arg, 1, &result);
3158 0 : if (!ok)
3159 0 : return;
3160 :
3161 0 : NPN_ReleaseVariantValue(&result);
3162 0 : delete rd;
3163 : }
3164 :
3165 : bool
3166 0 : checkGCRace(NPObject* npobj, const NPVariant* args, uint32_t argCount,
3167 : NPVariant* result)
3168 : {
3169 0 : if (1 != argCount || !NPVARIANT_IS_OBJECT(args[0]))
3170 0 : return false;
3171 :
3172 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3173 :
3174 : NPObject* localFunc =
3175 0 : NPN_CreateObject(npp, const_cast<NPClass*>(&kGCRaceClass));
3176 :
3177 : GCRaceData* rd =
3178 0 : new GCRaceData(npp, NPVARIANT_TO_OBJECT(args[0]), localFunc);
3179 0 : NPN_PluginThreadAsyncCall(npp, FinishGCRace, rd);
3180 :
3181 0 : OBJECT_TO_NPVARIANT(localFunc, *result);
3182 0 : return true;
3183 : }
3184 :
3185 : bool
3186 0 : hangPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount,
3187 : NPVariant* result)
3188 : {
3189 0 : mozilla::NoteIntentionalCrash("plugin");
3190 :
3191 : #ifdef XP_WIN
3192 : Sleep(100000000);
3193 : #else
3194 0 : pause();
3195 : #endif
3196 : // NB: returning true here means that we weren't terminated, and
3197 : // thus the hang detection/handling didn't work correctly. The
3198 : // test harness will succeed in calling this function, and the
3199 : // test will fail.
3200 0 : return true;
3201 : }
3202 :
3203 : #if defined(MOZ_WIDGET_GTK2)
3204 : bool
3205 0 : getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
3206 : NPVariant* result)
3207 : {
3208 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3209 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3210 0 : string sel = pluginGetClipboardText(id);
3211 :
3212 0 : uint32 len = sel.size();
3213 0 : char* selCopy = static_cast<char*>(NPN_MemAlloc(1 + len));
3214 0 : if (!selCopy)
3215 0 : return false;
3216 :
3217 0 : memcpy(selCopy, sel.c_str(), len);
3218 0 : selCopy[len] = '\0';
3219 :
3220 0 : STRINGN_TO_NPVARIANT(selCopy, len, *result);
3221 : // *result owns str now
3222 :
3223 0 : return true;
3224 : }
3225 :
3226 : bool
3227 0 : crashPluginInNestedLoop(NPObject* npobj, const NPVariant* args,
3228 : uint32_t argCount, NPVariant* result)
3229 : {
3230 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3231 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3232 0 : return pluginCrashInNestedLoop(id);
3233 : }
3234 :
3235 : bool
3236 0 : destroySharedGfxStuff(NPObject* npobj, const NPVariant* args,
3237 : uint32_t argCount, NPVariant* result)
3238 : {
3239 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3240 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3241 0 : return pluginDestroySharedGfxStuff(id);
3242 : }
3243 :
3244 : #else
3245 : bool
3246 : getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
3247 : NPVariant* result)
3248 : {
3249 : // XXX Not implemented!
3250 : return false;
3251 : }
3252 :
3253 : bool
3254 : crashPluginInNestedLoop(NPObject* npobj, const NPVariant* args,
3255 : uint32_t argCount, NPVariant* result)
3256 : {
3257 : // XXX Not implemented!
3258 : return false;
3259 : }
3260 :
3261 : bool
3262 : destroySharedGfxStuff(NPObject* npobj, const NPVariant* args,
3263 : uint32_t argCount, NPVariant* result)
3264 : {
3265 : // XXX Not implemented!
3266 : return false;
3267 : }
3268 : #endif
3269 :
3270 : bool
3271 0 : callOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
3272 : {
3273 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3274 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3275 :
3276 0 : if (id->callOnDestroy)
3277 0 : return false;
3278 :
3279 0 : if (1 != argCount || !NPVARIANT_IS_OBJECT(args[0]))
3280 0 : return false;
3281 :
3282 0 : id->callOnDestroy = NPVARIANT_TO_OBJECT(args[0]);
3283 0 : NPN_RetainObject(id->callOnDestroy);
3284 :
3285 0 : return true;
3286 : }
3287 :
3288 : // On Linux at least, a windowed plugin resize causes Flash Player to
3289 : // reconnect to the browser window. This method simulates that.
3290 : bool
3291 0 : reinitWidget(NPObject* npobj, const NPVariant* args, uint32_t argCount,
3292 : NPVariant* result)
3293 : {
3294 0 : if (argCount != 0)
3295 0 : return false;
3296 :
3297 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3298 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3299 :
3300 0 : if (!id->hasWidget)
3301 0 : return false;
3302 :
3303 0 : pluginWidgetInit(id, id->window.window);
3304 0 : return true;
3305 : }
3306 :
3307 : bool
3308 0 : propertyAndMethod(NPObject* npobj, const NPVariant* args, uint32_t argCount,
3309 : NPVariant* result)
3310 : {
3311 0 : INT32_TO_NPVARIANT(5, *result);
3312 0 : return true;
3313 : }
3314 :
3315 : // Returns top-level window activation state as indicated by Cocoa NPAPI's
3316 : // NPCocoaEventWindowFocusChanged events - 'true' if active, 'false' if not.
3317 : // Throws an exception if no events have been received and thus this state
3318 : // is unknown.
3319 : bool
3320 0 : getTopLevelWindowActivationState(NPObject* npobj, const NPVariant* args, uint32_t argCount,
3321 : NPVariant* result)
3322 : {
3323 0 : if (argCount != 0)
3324 0 : return false;
3325 :
3326 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3327 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3328 :
3329 : // Throw an exception for unknown state.
3330 0 : if (id->topLevelWindowActivationState == ACTIVATION_STATE_UNKNOWN) {
3331 0 : return false;
3332 : }
3333 :
3334 0 : if (id->topLevelWindowActivationState == ACTIVATION_STATE_ACTIVATED) {
3335 0 : BOOLEAN_TO_NPVARIANT(true, *result);
3336 0 : } else if (id->topLevelWindowActivationState == ACTIVATION_STATE_DEACTIVATED) {
3337 0 : BOOLEAN_TO_NPVARIANT(false, *result);
3338 : }
3339 :
3340 0 : return true;
3341 : }
3342 :
3343 : bool
3344 0 : getTopLevelWindowActivationEventCount(NPObject* npobj, const NPVariant* args, uint32_t argCount,
3345 : NPVariant* result)
3346 : {
3347 0 : if (argCount != 0)
3348 0 : return false;
3349 :
3350 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3351 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3352 :
3353 0 : INT32_TO_NPVARIANT(id->topLevelWindowActivationEventCount, *result);
3354 :
3355 0 : return true;
3356 : }
3357 :
3358 : // Returns top-level window activation state as indicated by Cocoa NPAPI's
3359 : // NPCocoaEventWindowFocusChanged events - 'true' if active, 'false' if not.
3360 : // Throws an exception if no events have been received and thus this state
3361 : // is unknown.
3362 : bool
3363 0 : getFocusState(NPObject* npobj, const NPVariant* args, uint32_t argCount,
3364 : NPVariant* result)
3365 : {
3366 0 : if (argCount != 0)
3367 0 : return false;
3368 :
3369 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3370 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3371 :
3372 : // Throw an exception for unknown state.
3373 0 : if (id->focusState == ACTIVATION_STATE_UNKNOWN) {
3374 0 : return false;
3375 : }
3376 :
3377 0 : if (id->focusState == ACTIVATION_STATE_ACTIVATED) {
3378 0 : BOOLEAN_TO_NPVARIANT(true, *result);
3379 0 : } else if (id->focusState == ACTIVATION_STATE_DEACTIVATED) {
3380 0 : BOOLEAN_TO_NPVARIANT(false, *result);
3381 : }
3382 :
3383 0 : return true;
3384 : }
3385 :
3386 : bool
3387 0 : getFocusEventCount(NPObject* npobj, const NPVariant* args, uint32_t argCount,
3388 : NPVariant* result)
3389 : {
3390 0 : if (argCount != 0)
3391 0 : return false;
3392 :
3393 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3394 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3395 :
3396 0 : INT32_TO_NPVARIANT(id->focusEventCount, *result);
3397 :
3398 0 : return true;
3399 : }
3400 :
3401 : bool
3402 0 : getEventModel(NPObject* npobj, const NPVariant* args, uint32_t argCount,
3403 : NPVariant* result)
3404 : {
3405 0 : if (argCount != 0)
3406 0 : return false;
3407 :
3408 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3409 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3410 :
3411 0 : INT32_TO_NPVARIANT(id->eventModel, *result);
3412 :
3413 0 : return true;
3414 : }
3415 :
3416 : static bool
3417 0 : ReflectorHasMethod(NPObject* npobj, NPIdentifier name)
3418 : {
3419 0 : return false;
3420 : }
3421 :
3422 : static bool
3423 0 : ReflectorHasProperty(NPObject* npobj, NPIdentifier name)
3424 : {
3425 0 : return true;
3426 : }
3427 :
3428 : static bool
3429 0 : ReflectorGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result)
3430 : {
3431 0 : if (NPN_IdentifierIsString(name)) {
3432 0 : char* s = NPN_UTF8FromIdentifier(name);
3433 0 : STRINGZ_TO_NPVARIANT(s, *result);
3434 0 : return true;
3435 : }
3436 :
3437 0 : INT32_TO_NPVARIANT(NPN_IntFromIdentifier(name), *result);
3438 0 : return true;
3439 : }
3440 :
3441 : static const NPClass kReflectorNPClass = {
3442 : NP_CLASS_STRUCT_VERSION,
3443 : NULL,
3444 : NULL,
3445 : NULL,
3446 : ReflectorHasMethod,
3447 : NULL,
3448 : NULL,
3449 : ReflectorHasProperty,
3450 : ReflectorGetProperty,
3451 : NULL,
3452 : NULL,
3453 : NULL,
3454 : NULL
3455 : };
3456 :
3457 : bool
3458 0 : getReflector(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
3459 : {
3460 0 : if (0 != argCount)
3461 0 : return false;
3462 :
3463 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3464 :
3465 : NPObject* reflector =
3466 : NPN_CreateObject(npp,
3467 0 : const_cast<NPClass*>(&kReflectorNPClass)); // retains
3468 0 : OBJECT_TO_NPVARIANT(reflector, *result);
3469 0 : return true;
3470 : }
3471 :
3472 0 : bool isVisible(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
3473 : {
3474 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3475 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3476 :
3477 0 : BOOLEAN_TO_NPVARIANT(id->window.clipRect.top != 0 ||
3478 : id->window.clipRect.left != 0 ||
3479 : id->window.clipRect.bottom != 0 ||
3480 : id->window.clipRect.right != 0, *result);
3481 0 : return true;
3482 : }
3483 :
3484 0 : bool getWindowPosition(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
3485 : {
3486 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3487 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3488 :
3489 0 : NPObject* window = NULL;
3490 0 : NPError err = NPN_GetValue(npp, NPNVWindowNPObject, &window);
3491 0 : if (NPERR_NO_ERROR != err || !window)
3492 0 : return false;
3493 :
3494 0 : NPIdentifier arrayID = NPN_GetStringIdentifier("Array");
3495 : NPVariant arrayFunctionV;
3496 0 : bool ok = NPN_GetProperty(npp, window, arrayID, &arrayFunctionV);
3497 :
3498 0 : NPN_ReleaseObject(window);
3499 :
3500 0 : if (!ok)
3501 0 : return false;
3502 :
3503 0 : if (!NPVARIANT_IS_OBJECT(arrayFunctionV)) {
3504 0 : NPN_ReleaseVariantValue(&arrayFunctionV);
3505 0 : return false;
3506 : }
3507 0 : NPObject* arrayFunction = NPVARIANT_TO_OBJECT(arrayFunctionV);
3508 :
3509 : NPVariant elements[4];
3510 0 : INT32_TO_NPVARIANT(id->window.x, elements[0]);
3511 0 : INT32_TO_NPVARIANT(id->window.y, elements[1]);
3512 0 : INT32_TO_NPVARIANT(id->window.width, elements[2]);
3513 0 : INT32_TO_NPVARIANT(id->window.height, elements[3]);
3514 :
3515 0 : ok = NPN_InvokeDefault(npp, arrayFunction, elements, 4, result);
3516 :
3517 0 : NPN_ReleaseObject(arrayFunction);
3518 :
3519 0 : return ok;
3520 : }
3521 :
3522 0 : bool constructObject(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
3523 : {
3524 0 : if (argCount == 0 || !NPVARIANT_IS_OBJECT(args[0]))
3525 0 : return false;
3526 :
3527 0 : NPObject* ctor = NPVARIANT_TO_OBJECT(args[0]);
3528 :
3529 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3530 :
3531 0 : return NPN_Construct(npp, ctor, args + 1, argCount - 1, result);
3532 : }
3533 :
3534 0 : bool setSitesWithData(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
3535 : {
3536 0 : if (argCount != 1 || !NPVARIANT_IS_STRING(args[0]))
3537 0 : return false;
3538 :
3539 : // Clear existing data.
3540 0 : delete sSitesWithData;
3541 :
3542 0 : const NPString* str = &NPVARIANT_TO_STRING(args[0]);
3543 0 : if (str->UTF8Length == 0)
3544 0 : return true;
3545 :
3546 : // Parse the comma-delimited string into a vector.
3547 0 : sSitesWithData = new list<siteData>;
3548 0 : const char* iterator = str->UTF8Characters;
3549 0 : const char* end = iterator + str->UTF8Length;
3550 0 : while (1) {
3551 0 : const char* next = strchr(iterator, ',');
3552 0 : if (!next)
3553 0 : next = end;
3554 :
3555 : // Parse out the three tokens into a siteData struct.
3556 0 : const char* siteEnd = strchr(iterator, ':');
3557 0 : *((char*) siteEnd) = NULL;
3558 0 : const char* flagsEnd = strchr(siteEnd + 1, ':');
3559 0 : *((char*) flagsEnd) = NULL;
3560 0 : *((char*) next) = NULL;
3561 :
3562 0 : siteData data;
3563 0 : data.site = string(iterator);
3564 0 : data.flags = atoi(siteEnd + 1);
3565 0 : data.age = atoi(flagsEnd + 1);
3566 :
3567 0 : sSitesWithData->push_back(data);
3568 :
3569 0 : if (next == end)
3570 : break;
3571 :
3572 0 : iterator = next + 1;
3573 : }
3574 :
3575 0 : return true;
3576 : }
3577 :
3578 0 : bool setSitesWithDataCapabilities(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
3579 : {
3580 0 : if (argCount != 1 || !NPVARIANT_IS_BOOLEAN(args[0]))
3581 0 : return false;
3582 :
3583 0 : sClearByAgeSupported = NPVARIANT_TO_BOOLEAN(args[0]);
3584 0 : return true;
3585 : }
3586 :
3587 0 : bool getLastKeyText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
3588 : NPVariant* result)
3589 : {
3590 0 : if (argCount != 0) {
3591 0 : return false;
3592 : }
3593 :
3594 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3595 0 : InstanceData* id = static_cast<InstanceData*>(npp->pdata);
3596 0 : STRINGZ_TO_NPVARIANT(NPN_StrDup(id->lastKeyText.c_str()), *result);
3597 0 : return true;
3598 : }
3599 :
3600 0 : bool getNPNVdocumentOrigin(NPObject* npobj, const NPVariant* args, uint32_t argCount,
3601 : NPVariant* result)
3602 : {
3603 0 : if (argCount != 0) {
3604 0 : return false;
3605 : }
3606 :
3607 0 : NPP npp = static_cast<TestNPObject*>(npobj)->npp;
3608 :
3609 0 : char *origin = NULL;
3610 0 : NPError err = NPN_GetValue(npp, NPNVdocumentOrigin, &origin);
3611 0 : if (err != NPERR_NO_ERROR) {
3612 0 : return false;
3613 : }
3614 :
3615 0 : STRINGZ_TO_NPVARIANT(origin, *result);
3616 0 : return true;
3617 519 : }
|