]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/dynload.cpp
Avoid using buffer of already deallocated string in wxHTMLDataObject.
[wxWidgets.git] / src / common / dynload.cpp
index e342678774bf0f193c9f201bb4d63f74dc97a94f..7d26dc392f8fe3e3d33d18869c59d97d9c22fe28 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:         dynload.cpp
+// Name:         src/common/dynload.cpp
 // Purpose:      Dynamic loading framework
 // Author:       Ron Lee, David Falkinder, Vadim Zeitlin and a cast of 1000's
 //               (derived in part from dynlib.cpp (c) 1998 Guilhem Lavaux)
 // Licence:      wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "dynload.h"
-#endif
-
 // ----------------------------------------------------------------------------
 // headers
 // ----------------------------------------------------------------------------
     #include "wx/intl.h"
     #include "wx/hash.h"
     #include "wx/utils.h"
+    #include "wx/module.h"
 #endif
 
 #include "wx/strconv.h"
 
 #include "wx/dynload.h"
-#include "wx/module.h"
 
 
 // ---------------------------------------------------------------------------
@@ -58,15 +54,14 @@ public:
     // TODO: create ms_classes on demand, why always preallocate it?
     virtual bool OnInit()
     {
-        wxPluginLibrary::ms_classes = new wxDLImports(wxKEY_STRING);
+        wxPluginLibrary::ms_classes = new wxDLImports;
         wxPluginManager::CreateManifest();
-        return TRUE;
+        return true;
     }
 
     virtual void OnExit()
     {
-        delete wxPluginLibrary::ms_classes;
-        wxPluginLibrary::ms_classes = NULL;
+        wxDELETE(wxPluginLibrary::ms_classes);
         wxPluginManager::ClearManifest();
     }
 
@@ -81,13 +76,37 @@ wxPluginLibrary::wxPluginLibrary(const wxString &libname, int flags)
         : m_linkcount(1)
         , m_objcount(0)
 {
-    m_before = wxClassInfo::sm_first;
+    const wxClassInfo* const oldFirst = wxClassInfo::GetFirst();
     Load( libname, flags );
-    m_after = wxClassInfo::sm_first;
+
+    // It is simple to know what is the first object in the linked list of
+    // wxClassInfo that we registered (it's also the last one chronologically),
+    // it's just the new head of the wxClassInfo list:
+    m_ourFirst = wxClassInfo::GetFirst();
+
+    // But to find the first wxClassInfo created by this library we need to
+    // iterate until we get to the previous head as we don't have the links in
+    // the backwards direction:
+    if ( m_ourFirst != oldFirst )
+    {
+        for ( const wxClassInfo* info = m_ourFirst; ; info = info->GetNext() )
+        {
+            if ( info->GetNext() == oldFirst )
+            {
+                m_ourLast = info;
+                break;
+            }
+        }
+    }
+    else // We didn't register any classes at all.
+    {
+        m_ourFirst =
+        m_ourLast = NULL;
+    }
 
     if( m_handle != 0 )
     {
-        UpdateClassInfo();
+        UpdateClasses();
         RegisterModules();
     }
     else
@@ -102,14 +121,14 @@ wxPluginLibrary::~wxPluginLibrary()
     if( m_handle != 0 )
     {
         UnregisterModules();
-        RestoreClassInfo();
+        RestoreClasses();
     }
 }
 
 wxPluginLibrary *wxPluginLibrary::RefLib()
 {
     wxCHECK_MSG( m_linkcount > 0, NULL,
-                 _T("Library had been already deleted!") );
+                 wxT("Library had been already deleted!") );
 
     ++m_linkcount;
     return this;
@@ -118,69 +137,55 @@ wxPluginLibrary *wxPluginLibrary::RefLib()
 bool wxPluginLibrary::UnrefLib()
 {
     wxASSERT_MSG( m_objcount == 0,
-                  _T("Library unloaded before all objects were destroyed") );
+                  wxT("Library unloaded before all objects were destroyed") );
 
-    if ( --m_linkcount == 0 )
+    if ( m_linkcount == 0 || --m_linkcount == 0 )
     {
         delete this;
-        return TRUE;
+        return true;
     }
 
-    return FALSE;
+    return false;
 }
 
 // ------------------------
 // Private methods
 // ------------------------
 
-void wxPluginLibrary::UpdateClassInfo()
+void wxPluginLibrary::UpdateClasses()
 {
-    wxClassInfo     *info;
-    wxHashTable     *t = wxClassInfo::sm_classTable;
-
-        // FIXME: Below is simply a cut and paste specialisation of
-        //        wxClassInfo::InitializeClasses.  Once this stabilises,
-        //        the two should probably be merged.
-        //
-        //        Actually it's becoming questionable whether we should merge
-        //        this info with the main ClassInfo tables since we can nearly
-        //        handle this completely internally now and it does expose
-        //        certain (minimal % user_stupidy) risks.
-
-    for(info = m_after; info != m_before; info = info->m_next)
+    if ( !m_ourFirst )
+        return;
+
+    for ( const wxClassInfo *info = m_ourFirst; ; info = info->GetNext() )
     {
-        if( info->m_className )
+        if( info->GetClassName() )
         {
-            if( t->Get(info->m_className) == 0 )
-                t->Put(info->m_className, (wxObject *)info);
-
             // Hash all the class names into a local table too so
             // we can quickly find the entry they correspond to.
-            (*ms_classes)[info->m_className] = this;
+            (*ms_classes)[info->GetClassName()] = this;
         }
+
+        if ( info == m_ourLast )
+            break;
     }
 }
 
-void wxPluginLibrary::RestoreClassInfo()
+void wxPluginLibrary::RestoreClasses()
 {
-    wxClassInfo *info;
+    // Check if there is a need to restore classes.
+    if (!ms_classes)
+        return;
 
-    for(info = m_after; info != m_before; info = info->m_next)
-    {
-        wxClassInfo::sm_classTable->Delete(info->m_className);
-        ms_classes->erase(ms_classes->find(info->m_className));
-    }
+    if ( !m_ourFirst )
+        return;
 
-    if( wxClassInfo::sm_first == m_after )
-        wxClassInfo::sm_first = m_before;
-    else
+    for ( const wxClassInfo *info = m_ourFirst; ; info = info->GetNext() )
     {
-        info = wxClassInfo::sm_first;
-        while( info->m_next && info->m_next != m_after ) info = info->m_next;
-
-        wxASSERT_MSG( info, _T("ClassInfo from wxPluginLibrary not found on purge"));
+        ms_classes->erase(ms_classes->find(info->GetClassName()));
 
-        info->m_next = m_before;
+        if ( info == m_ourLast )
+            break;
     }
 }
 
@@ -195,18 +200,24 @@ void wxPluginLibrary::RegisterModules()
     // though, as there is currently no way to Unregister it without it.
 
     wxASSERT_MSG( m_linkcount == 1,
-                  _T("RegisterModules should only be called for the first load") );
+                  wxT("RegisterModules should only be called for the first load") );
 
-    for ( wxClassInfo *info = m_after; info != m_before; info = info->m_next)
+    if ( m_ourFirst )
     {
-        if( info->IsKindOf(CLASSINFO(wxModule)) )
+        for ( const wxClassInfo *info = m_ourFirst; ; info = info->GetNext() )
         {
-            wxModule *m = wxDynamicCast(info->CreateObject(), wxModule);
+            if( info->IsKindOf(wxCLASSINFO(wxModule)) )
+            {
+                wxModule *m = wxDynamicCast(info->CreateObject(), wxModule);
 
-            wxASSERT_MSG( m, _T("wxDynamicCast of wxModule failed") );
+                wxASSERT_MSG( m, wxT("wxDynamicCast of wxModule failed") );
 
-            m_wxmodules.push_back(m);
-            wxModule::RegisterModule(m);
+                m_wxmodules.push_back(m);
+                wxModule::RegisterModule(m);
+            }
+
+            if ( info == m_ourLast )
+                break;
         }
     }
 
@@ -218,7 +229,7 @@ void wxPluginLibrary::RegisterModules()
     {
         if( !(*it)->Init() )
         {
-            wxLogDebug(_T("wxModule::Init() failed for wxPluginLibrary"));
+            wxLogDebug(wxT("wxModule::Init() failed for wxPluginLibrary"));
 
             // XXX: Watch this, a different hash implementation might break it,
             //      a good hash implementation would let us fix it though.
@@ -252,7 +263,8 @@ void wxPluginLibrary::UnregisterModules()
     for ( it = m_wxmodules.begin(); it != m_wxmodules.end(); ++it )
         wxModule::UnregisterModule( *it );
 
-    WX_CLEAR_LIST(wxModuleList, m_wxmodules);
+    // NB: content of the list was deleted by UnregisterModule calls above:
+    m_wxmodules.clear();
 }
 
 
@@ -272,7 +284,7 @@ wxPluginManager::LoadLibrary(const wxString &libname, int flags)
     wxString realname(libname);
 
     if( !(flags & wxDL_VERBATIM) )
-        realname += wxDynamicLibrary::GetDllExt();
+        realname += wxDynamicLibrary::GetDllExt(wxDL_MODULE);
 
     wxPluginLibrary *entry;
 
@@ -287,8 +299,8 @@ wxPluginManager::LoadLibrary(const wxString &libname, int flags)
 
     if ( entry )
     {
-        wxLogTrace(_T("dll"),
-                   _T("LoadLibrary(%s): already loaded."), realname.c_str());
+        wxLogTrace(wxT("dll"),
+                   wxT("LoadLibrary(%s): already loaded."), realname.c_str());
 
         entry->RefLib();
     }
@@ -300,20 +312,20 @@ wxPluginManager::LoadLibrary(const wxString &libname, int flags)
         {
             (*ms_manifest)[realname] = entry;
 
-            wxLogTrace(_T("dll"),
-                       _T("LoadLibrary(%s): loaded ok."), realname.c_str());
+            wxLogTrace(wxT("dll"),
+                       wxT("LoadLibrary(%s): loaded ok."), realname.c_str());
 
         }
         else
         {
-            wxLogTrace(_T("dll"),
-                       _T("LoadLibrary(%s): failed to load."), realname.c_str());
+            wxLogTrace(wxT("dll"),
+                       wxT("LoadLibrary(%s): failed to load."), realname.c_str());
 
             // we have created entry just above
             if ( !entry->UnrefLib() )
             {
                 // ... so UnrefLib() is supposed to delete it
-                wxFAIL_MSG( _T("Currently linked library is not loaded?") );
+                wxFAIL_MSG( wxT("Currently linked library is not loaded?") );
             }
 
             entry = NULL;
@@ -331,30 +343,30 @@ bool wxPluginManager::UnloadLibrary(const wxString& libname)
 
     if ( !entry )
     {
-        realname += wxDynamicLibrary::GetDllExt();
+        realname += wxDynamicLibrary::GetDllExt(wxDL_MODULE);
 
         entry = FindByName(realname);
     }
 
     if ( !entry )
     {
-        wxLogDebug(_T("Attempt to unload library '%s' which is not loaded."),
+        wxLogDebug(wxT("Attempt to unload library '%s' which is not loaded."),
                    libname.c_str());
 
-        return FALSE;
+        return false;
     }
 
-    wxLogTrace(_T("dll"), _T("UnloadLibrary(%s)"), realname.c_str());
+    wxLogTrace(wxT("dll"), wxT("UnloadLibrary(%s)"), realname.c_str());
 
     if ( !entry->UnrefLib() )
     {
         // not really unloaded yet
-        return FALSE;
+        return false;
     }
 
     ms_manifest->erase(ms_manifest->find(realname));
 
-    return TRUE;
+    return true;
 }
 
 // ------------------------
@@ -370,7 +382,7 @@ bool wxPluginManager::Load(const wxString &libname, int flags)
 
 void wxPluginManager::Unload()
 {
-    wxCHECK_RET( m_entry, _T("unloading an invalid wxPluginManager?") );
+    wxCHECK_RET( m_entry, wxT("unloading an invalid wxPluginManager?") );
 
     for ( wxDLManifest::iterator i = ms_manifest->begin();
           i != ms_manifest->end();
@@ -388,225 +400,4 @@ void wxPluginManager::Unload()
     m_entry = NULL;
 }
 
-
-
-#if WXWIN_COMPATIBILITY_2_2
-
-wxPluginLibrary *wxPluginManager::GetObjectFromHandle(wxDllType handle)
-{
-    for ( wxDLManifest::iterator i = ms_manifest->begin();
-          i != ms_manifest->end();
-          ++i )
-    {
-        wxPluginLibrary * const lib = i->second;
-
-        if ( lib->GetLibHandle() == handle )
-            return lib;
-    }
-
-    return NULL;
-}
-
-// ---------------------------------------------------------------------------
-// wxDllLoader   (all these methods are static)
-// ---------------------------------------------------------------------------
-
-
-wxDllType wxDllLoader::LoadLibrary(const wxString &name, bool *success)
-{
-    wxPluginLibrary *p = wxPluginManager::LoadLibrary
-                         (
-                            name,
-                            wxDL_DEFAULT | wxDL_VERBATIM | wxDL_NOSHARE
-                         );
-
-    if ( success )
-        *success = p != NULL;
-
-    return p ? p->GetLibHandle() : 0;
-}
-
-void wxDllLoader::UnloadLibrary(wxDllType handle)
-{
-    wxPluginLibrary *p = wxPluginManager::GetObjectFromHandle(handle);
-
-    wxCHECK_RET( p, _T("Unloading a library not loaded with wxDllLoader?") );
-
-    p->UnrefLib();
-}
-
-void *
-wxDllLoader::GetSymbol(wxDllType dllHandle, const wxString &name, bool *success)
-{
-    wxPluginLibrary *p = wxPluginManager::GetObjectFromHandle(dllHandle);
-
-    if ( !p )
-    {
-        wxFAIL_MSG( _T("Using a library not loaded with wxDllLoader?") );
-
-        if ( success )
-            *success = FALSE;
-
-        return NULL;
-    }
-
-    return p->GetSymbol(name, success);
-}
-
-
-// ---------------------------------------------------------------------------
-// Global variables
-// ---------------------------------------------------------------------------
-
-wxLibraries wxTheLibraries;
-
-// ============================================================================
-// implementation
-// ============================================================================
-
-// construct the full name from the base shared object name: adds a .dll
-// suffix under Windows or .so under Unix
-static wxString ConstructLibraryName(const wxString& basename)
-{
-    wxString fullname;
-    fullname << basename << wxDllLoader::GetDllExt();
-
-    return fullname;
-}
-
-// ---------------------------------------------------------------------------
-// wxLibrary (one instance per dynamic library)
-// ---------------------------------------------------------------------------
-
-wxLibrary::wxLibrary(wxDllType handle)
-{
-    typedef wxClassInfo *(*t_get_first)(void);
-    t_get_first get_first;
-
-    m_handle = handle;
-
-    // Some system may use a local heap for library.
-    get_first = (t_get_first)GetSymbol(_T("wxGetClassFirst"));
-    // It is a wxWindows DLL.
-    if (get_first)
-        PrepareClasses(get_first());
-}
-
-wxLibrary::~wxLibrary()
-{
-    if ( m_handle )
-    {
-        wxDllLoader::UnloadLibrary(m_handle);
-    }
-}
-
-wxObject *wxLibrary::CreateObject(const wxString& name)
-{
-    wxClassInfo *info = (wxClassInfo *)classTable.Get(name);
-
-    if (!info)
-        return NULL;
-
-    return info->CreateObject();
-}
-
-void wxLibrary::PrepareClasses(wxClassInfo *first)
-{
-    // Index all class infos by their class name
-    wxClassInfo *info = first;
-    while (info)
-    {
-        if (info->m_className)
-            classTable.Put(info->m_className, (wxObject *)info);
-        info = info->m_next;
-    }
-
-#if !wxUSE_EXTENDED_RTTI
-    // Set base pointers for each wxClassInfo
-    info = first;
-    while (info)
-    {
-        if (info->GetBaseClassName1())
-            info->m_baseInfo1 = (wxClassInfo *)classTable.Get(info->GetBaseClassName1());
-        if (info->GetBaseClassName2())
-            info->m_baseInfo2 = (wxClassInfo *)classTable.Get(info->GetBaseClassName2());
-        info = info->m_next;
-    }
-#endif
-}
-
-void *wxLibrary::GetSymbol(const wxString& symbname)
-{
-   return wxDllLoader::GetSymbol(m_handle, symbname);
-}
-
-
-// ---------------------------------------------------------------------------
-// wxLibraries (only one instance should normally exist)
-// ---------------------------------------------------------------------------
-
-wxLibraries::wxLibraries():m_loaded(wxKEY_STRING)
-{
-}
-
-wxLibraries::~wxLibraries()
-{
-    wxNode *node = m_loaded.First();
-
-    while (node) {
-        wxLibrary *lib = (wxLibrary *)node->Data();
-        delete lib;
-
-        node = node->Next();
-    }
-}
-
-wxLibrary *wxLibraries::LoadLibrary(const wxString& name)
-{
-    wxLibrary   *lib;
-    wxClassInfo *old_sm_first;
-    wxNode      *node = m_loaded.Find(name.GetData());
-
-    if (node != NULL)
-        return ((wxLibrary *)node->Data());
-
-    // If DLL shares data, this is necessary.
-    old_sm_first = wxClassInfo::sm_first;
-    wxClassInfo::sm_first = NULL;
-
-    wxString libname = ConstructLibraryName(name);
-
-    bool success = FALSE;
-    wxDllType handle = wxDllLoader::LoadLibrary(libname, &success);
-    if(success)
-    {
-       lib = new wxLibrary(handle);
-       wxClassInfo::sm_first = old_sm_first;
-
-       m_loaded.Append(name.GetData(), lib);
-    }
-    else
-       lib = NULL;
-    return lib;
-}
-
-wxObject *wxLibraries::CreateObject(const wxString& path)
-{
-    wxNode *node = m_loaded.First();
-    wxObject *obj;
-
-    while (node) {
-        obj = ((wxLibrary *)node->Data())->CreateObject(path);
-        if (obj)
-            return obj;
-
-        node = node->Next();
-    }
-    return NULL;
-}
-
-#endif  // WXWIN_COMPATIBILITY_2_2
-
-
 #endif  // wxUSE_DYNAMIC_LOADER
-