LCOV - code coverage report
Current view: directory - dom/plugins/test/testplugin - nptest.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 1676 12 0.7 %
Date: 2012-06-02 Functions: 166 5 3.0 %

       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 :                  &param, 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 : }

Generated by: LCOV version 1.7