Bug 615881: Fix several bugs related to the handling of NPAPI's NPPluginFuncs structure. r=bsmedberg a=blocking2.0final+
authorJosh Aas <joshmoz@gmail.com>
Fri, 03 Dec 2010 00:20:59 -0500
changeset 58535 9280c6d82204bdea2901e5e24726186370f86624
parent 58534 a4813c8be814ca7dd0faaedb9dc6d30791f34de8
child 58536 e42651bbc73ef45b2d6f76b6ad3e85cb43a4cfae
push id17340
push userjosh@mozilla.com
push dateFri, 03 Dec 2010 05:23:11 +0000
treeherdermozilla-central@e42651bbc73e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg, blocking2.0final
bugs615881
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 615881: Fix several bugs related to the handling of NPAPI's NPPluginFuncs structure. r=bsmedberg a=blocking2.0final+
dom/plugins/PluginModuleChild.cpp
modules/plugin/base/src/nsNPAPIPlugin.cpp
modules/plugin/sdk/samples/basic/mac/BasicPlugin.c
modules/plugin/sdk/samples/basic/unix/BasicPlugin.c
modules/plugin/sdk/samples/npruntime/np_entry.cpp
modules/plugin/test/testplugin/nptest.cpp
--- a/dom/plugins/PluginModuleChild.cpp
+++ b/dom/plugins/PluginModuleChild.cpp
@@ -200,16 +200,17 @@ PluginModuleChild::Init(const std::strin
     NS_ASSERTION(NS_OK == rv, "trouble with mPluginFile");
     NS_ASSERTION(mLibrary, "couldn't open shared object");
 
     if (!Open(aChannel, aParentProcessHandle, aIOLoop))
         return false;
 
     memset((void*) &mFunctions, 0, sizeof(mFunctions));
     mFunctions.size = sizeof(mFunctions);
+    mFunctions.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
 
     // TODO: use PluginPRLibrary here
 
 #if defined(OS_LINUX)
     mShutdownFunc =
         (NP_PLUGINSHUTDOWN) PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
 
     // create the new plugin handler
--- a/modules/plugin/base/src/nsNPAPIPlugin.cpp
+++ b/modules/plugin/base/src/nsNPAPIPlugin.cpp
@@ -237,24 +237,23 @@ NS_IMPL_ISUPPORTS1(nsNPAPIPlugin, nsIPlu
 nsNPAPIPlugin::nsNPAPIPlugin()
 {
 #if defined(XP_MACOSX) && !defined(__LP64__)
   mPluginRefNum = -1;
 #endif
 
   memset((void*)&mPluginFuncs, 0, sizeof(mPluginFuncs));
   mPluginFuncs.size = sizeof(mPluginFuncs);
+  mPluginFuncs.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
 
   mLibrary = nsnull;
 }
 
 nsNPAPIPlugin::~nsNPAPIPlugin()
 {
-  // reset the callbacks list
-  memset((void*) &mPluginFuncs, 0, sizeof(mPluginFuncs));
   delete mLibrary;
   mLibrary = nsnull;
 }
 
 #if defined(XP_MACOSX) && !defined(__LP64__)
 void
 nsNPAPIPlugin::SetPluginRefNum(short aRefNum)
 {
--- a/modules/plugin/sdk/samples/basic/mac/BasicPlugin.c
+++ b/modules/plugin/sdk/samples/basic/mac/BasicPlugin.c
@@ -37,18 +37,21 @@ NPError NP_Initialize(NPNetscapeFuncs* b
   browser = browserFuncs;
 
   return NPERR_NO_ERROR;
 }
 
 // Symbol called by the browser to get the plugin's function list
 NPError NP_GetEntryPoints(NPPluginFuncs* pluginFuncs)
 {
-  pluginFuncs->version = 11;
-  pluginFuncs->size = sizeof(pluginFuncs);
+  // Check the size of the provided structure based on the offset of the
+  // last member we need.
+  if (pluginFuncs->size < (offsetof(NPPluginFuncs, setvalue) + sizeof(void*)))
+    return NPERR_INVALID_FUNCTABLE_ERROR;
+
   pluginFuncs->newp = NPP_New;
   pluginFuncs->destroy = NPP_Destroy;
   pluginFuncs->setwindow = NPP_SetWindow;
   pluginFuncs->newstream = NPP_NewStream;
   pluginFuncs->destroystream = NPP_DestroyStream;
   pluginFuncs->asfile = NPP_StreamAsFile;
   pluginFuncs->writeready = NPP_WriteReady;
   pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
--- a/modules/plugin/sdk/samples/basic/unix/BasicPlugin.c
+++ b/modules/plugin/sdk/samples/basic/unix/BasicPlugin.c
@@ -53,36 +53,16 @@
 static NPNetscapeFuncs* sBrowserFuncs = NULL;
 
 typedef struct InstanceData {
   NPP npp;
   NPWindow window;
 } InstanceData;
 
 static void
-fillPluginFunctionTable(NPPluginFuncs* pFuncs)
-{
-  pFuncs->version = 11;
-  pFuncs->size = sizeof(*pFuncs);
-  pFuncs->newp = NPP_New;
-  pFuncs->destroy = NPP_Destroy;
-  pFuncs->setwindow = NPP_SetWindow;
-  pFuncs->newstream = NPP_NewStream;
-  pFuncs->destroystream = NPP_DestroyStream;
-  pFuncs->asfile = NPP_StreamAsFile;
-  pFuncs->writeready = NPP_WriteReady;
-  pFuncs->write = NPP_Write;
-  pFuncs->print = NPP_Print;
-  pFuncs->event = NPP_HandleEvent;
-  pFuncs->urlnotify = NPP_URLNotify;
-  pFuncs->getvalue = NPP_GetValue;
-  pFuncs->setvalue = NPP_SetValue;
-}
-
-static void
 drawWindow(InstanceData* instanceData, GdkDrawable* gdkWindow)
 {
   NPWindow window = instanceData->window;
   int x = window.x;
   int y = window.y;
   int width = window.width;
   int height = window.height;
 
@@ -121,17 +101,34 @@ drawWindow(InstanceData* instanceData, G
   g_object_unref(gdkContext);
 }
 
 NP_EXPORT(NPError)
 NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs)
 {
   sBrowserFuncs = bFuncs;
 
-  fillPluginFunctionTable(pFuncs);
+  // Check the size of the provided structure based on the offset of the
+  // last member we need.
+  if (pFuncs->size < (offsetof(NPPluginFuncs, setvalue) + sizeof(void*)))
+    return NPERR_INVALID_FUNCTABLE_ERROR;
+
+  pFuncs->newp = NPP_New;
+  pFuncs->destroy = NPP_Destroy;
+  pFuncs->setwindow = NPP_SetWindow;
+  pFuncs->newstream = NPP_NewStream;
+  pFuncs->destroystream = NPP_DestroyStream;
+  pFuncs->asfile = NPP_StreamAsFile;
+  pFuncs->writeready = NPP_WriteReady;
+  pFuncs->write = NPP_Write;
+  pFuncs->print = NPP_Print;
+  pFuncs->event = NPP_HandleEvent;
+  pFuncs->urlnotify = NPP_URLNotify;
+  pFuncs->getvalue = NPP_GetValue;
+  pFuncs->setvalue = NPP_SetValue;
 
   return NPERR_NO_ERROR;
 }
 
 NP_EXPORT(char*)
 NP_GetPluginVersion()
 {
   return PLUGIN_VERSION;
--- a/modules/plugin/sdk/samples/npruntime/np_entry.cpp
+++ b/modules/plugin/sdk/samples/npruntime/np_entry.cpp
@@ -50,34 +50,32 @@ NPNetscapeFuncs NPNFuncs;
 
 #ifdef XP_WIN
 
 NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs)
 {
   if(pFuncs == NULL)
     return NPERR_INVALID_FUNCTABLE_ERROR;
 
-  if(pFuncs->size < sizeof(NPPluginFuncs))
+  if(pFuncs->size < (offsetof(NPPluginFuncs, setvalue) + sizeof(void*)))
     return NPERR_INVALID_FUNCTABLE_ERROR;
 
-  pFuncs->version       = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
   pFuncs->newp          = NPP_New;
   pFuncs->destroy       = NPP_Destroy;
   pFuncs->setwindow     = NPP_SetWindow;
   pFuncs->newstream     = NPP_NewStream;
   pFuncs->destroystream = NPP_DestroyStream;
   pFuncs->asfile        = NPP_StreamAsFile;
   pFuncs->writeready    = NPP_WriteReady;
   pFuncs->write         = NPP_Write;
   pFuncs->print         = NPP_Print;
   pFuncs->event         = NPP_HandleEvent;
   pFuncs->urlnotify     = NPP_URLNotify;
   pFuncs->getvalue      = NPP_GetValue;
   pFuncs->setvalue      = NPP_SetValue;
-  pFuncs->javaClass     = NULL;
 
   return NPERR_NO_ERROR;
 }
 
 #endif /* XP_WIN */
 
 char *NPP_GetMIMEDescription();
 
--- a/modules/plugin/test/testplugin/nptest.cpp
+++ b/modules/plugin/test/testplugin/nptest.cpp
@@ -564,33 +564,38 @@ NP_GetValue(void* future, NPPVariable aV
     default:
       return NPERR_INVALID_PARAM;
       break;
   }
   return NPERR_NO_ERROR;
 }
 #endif
 
-static void fillPluginFunctionTable(NPPluginFuncs* pFuncs)
+static bool fillPluginFunctionTable(NPPluginFuncs* pFuncs)
 {
-  pFuncs->version = 11;
-  pFuncs->size = sizeof(*pFuncs);
+  // Check the size of the provided structure based on the offset of the
+  // last member we need.
+  if (pFuncs->size < (offsetof(NPPluginFuncs, setvalue) + sizeof(void*)))
+    return false;
+
   pFuncs->newp = NPP_New;
   pFuncs->destroy = NPP_Destroy;
   pFuncs->setwindow = NPP_SetWindow;
   pFuncs->newstream = NPP_NewStream;
   pFuncs->destroystream = NPP_DestroyStream;
   pFuncs->asfile = NPP_StreamAsFile;
   pFuncs->writeready = NPP_WriteReady;
   pFuncs->write = NPP_Write;
   pFuncs->print = NPP_Print;
   pFuncs->event = NPP_HandleEvent;
   pFuncs->urlnotify = testplugin_URLNotify;
   pFuncs->getvalue = NPP_GetValue;
   pFuncs->setvalue = NPP_SetValue;
+
+  return true;
 }
 
 #if defined(XP_MACOSX)
 NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs)
 #elif defined(XP_WIN) || defined(XP_OS2)
 NPError OSCALL NP_Initialize(NPNetscapeFuncs* bFuncs)
 #elif defined(XP_UNIX)
 NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs)
@@ -615,30 +620,35 @@ NP_EXPORT(NPError) NP_Initialize(NPNetsc
   sNPClass.hasProperty =    (NPHasPropertyFunctionPtr)scriptableHasProperty;
   sNPClass.getProperty =    (NPGetPropertyFunctionPtr)scriptableGetProperty;
   sNPClass.setProperty =    (NPSetPropertyFunctionPtr)scriptableSetProperty;
   sNPClass.removeProperty = (NPRemovePropertyFunctionPtr)scriptableRemoveProperty;
   sNPClass.enumerate =      (NPEnumerationFunctionPtr)scriptableEnumerate;
   sNPClass.construct =      (NPConstructFunctionPtr)scriptableConstruct;
 
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
-  fillPluginFunctionTable(pFuncs);
+  if (!fillPluginFunctionTable(pFuncs)) {
+    return NPERR_INVALID_FUNCTABLE_ERROR;
+  }
 #endif
 
   return NPERR_NO_ERROR;
 }
 
 #if defined(XP_MACOSX)
 NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs)
 #elif defined(XP_WIN) || defined(XP_OS2)
 NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs)
 #endif
 #if defined(XP_MACOSX) || defined(XP_WIN) || defined(XP_OS2)
 {
-  fillPluginFunctionTable(pFuncs);
+  if (!fillPluginFunctionTable(pFuncs)) {
+    return NPERR_INVALID_FUNCTABLE_ERROR;
+  }
+
   return NPERR_NO_ERROR;
 }
 #endif
 
 #if defined(XP_UNIX)
 NP_EXPORT(NPError) NP_Shutdown()
 #elif defined(XP_WIN) || defined(XP_OS2)
 NPError OSCALL NP_Shutdown()