mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-09-23 06:33:59 +08:00
Make wxXmlInitResourceModule() safer to use
This function unconditionally added a new wxXmlResourceModule object to the modules list which could result in problems if it had been already initialized. Ensure that we do this only if necessary by calling the new function added to wxModule which checks if the module is already known and adds and initializes only this module if it is not. See #26111. Closes #26039.
This commit is contained in:
@@ -54,6 +54,10 @@ public:
|
||||
|
||||
static void UnregisterModule(wxModule *module);
|
||||
|
||||
// Initialize the module with the given type information if it's not
|
||||
// already initialized. This is for internal use only currently.
|
||||
static void AddModuleIfNecessary(const wxClassInfo *classInfo);
|
||||
|
||||
protected:
|
||||
static wxModuleList ms_modules;
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "wx/log.h"
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
|
||||
#define TRACE_MODULE wxT("module")
|
||||
|
||||
wxIMPLEMENT_ABSTRACT_CLASS(wxModule, wxObject);
|
||||
@@ -148,6 +150,43 @@ bool wxModule::DoInitializeModule(wxModule *module,
|
||||
return true;
|
||||
}
|
||||
|
||||
void wxModule::AddModuleIfNecessary(const wxClassInfo *classInfo)
|
||||
{
|
||||
wxCHECK_RET( classInfo, wxS("Valid class info must be provided") );
|
||||
wxCHECK_RET( classInfo->IsKindOf(wxCLASSINFO(wxModule)),
|
||||
wxS("Class info must be for wxModule-derived class") );
|
||||
|
||||
const wxString className(classInfo->GetClassName());
|
||||
for ( wxModuleList::const_iterator it = ms_modules.begin();
|
||||
it != ms_modules.end();
|
||||
++it )
|
||||
{
|
||||
if ( (*it)->GetClassInfo()->GetClassName() == className )
|
||||
{
|
||||
// Already initialized or at least registered and will be
|
||||
// initialized later.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<wxModule>
|
||||
module{static_cast<wxModule*>(classInfo->CreateObject())};
|
||||
|
||||
// Do not call RegisterModule() here as it would add it to ms_modules which
|
||||
// would result in it being added twice as DoInitializeModule() would do it
|
||||
// too on success.
|
||||
module->m_state = State_Registered;
|
||||
|
||||
if ( !DoInitializeModule(module.get(), ms_modules) )
|
||||
{
|
||||
// Error is already given by DoInitializeModule().
|
||||
return;
|
||||
}
|
||||
|
||||
// Module is now owned by ms_modules.
|
||||
module.release();
|
||||
}
|
||||
|
||||
// Initialize user-defined modules
|
||||
bool wxModule::InitializeModules()
|
||||
{
|
||||
|
||||
+11
-3
@@ -3255,9 +3255,17 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxXmlResourceModule, wxModule);
|
||||
// then the built-in module system won't pick this one up. Add it manually.
|
||||
void wxXmlInitResourceModule()
|
||||
{
|
||||
wxModule* module = new wxXmlResourceModule;
|
||||
wxModule::RegisterModule(module);
|
||||
wxModule::InitializeModules();
|
||||
// Only add the module if the module system is already initialized,
|
||||
// otherwise it will be added automatically when it is done as it will be
|
||||
// known to the module system at that time (this happens as soon as the
|
||||
// code containing this function is loaded from a shared library and if
|
||||
// this function is running, it must have been already loaded!).
|
||||
if ( wxModule::AreInitialized() )
|
||||
{
|
||||
// Still check that this module is not already registered, as could
|
||||
// happen if this function is called multiple times, for example.
|
||||
wxModule::AddModuleIfNecessary(wxCLASSINFO(wxXmlResourceModule));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // wxUSE_XRC
|
||||
|
||||
Reference in New Issue
Block a user