From 9256b051fcd41bc7fe2a0a0e3c31a4d811fe1656 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Thu, 20 Nov 2025 23:56:41 +0000 Subject: [PATCH] Delay running the type creation event until after initialisation. Doing this during the ctor can run into circumstances where the vtable has not been fully initialised and the call gets routed to the pure virtual implementation causing a crash. --- include/serialize.h | 9 ++++++++- src/modulemanager.cpp | 1 + src/serialize.cpp | 24 ++++++++++++++++++------ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/include/serialize.h b/include/serialize.h index 0212ccd3a..59df4dbe1 100644 --- a/include/serialize.h +++ b/include/serialize.h @@ -76,6 +76,7 @@ namespace Serialize extern void RegisterTypes(); extern void CheckTypes(); + extern void CreateTypes(); class Type; template class Checker; @@ -148,8 +149,11 @@ class CoreExport Serialize::Type : public Base { private: + /** Whether modules have been informed about the creation of this type yet. */ + bool created = false; + /** The name of this type in the database (e.g. NickAlias). */ - Anope::string name; + const Anope::string name; /** The module which owns this type, or nullptr if it belongs to the core. * Some database backends use this to put third-party module data into their @@ -184,6 +188,9 @@ public: /** Destroys a serializable type. */ ~Type(); + /** Informs modules about the creation of this type. */ + void Create(); + /** Checks for and applies any pending object updates for this type. */ void Check(); diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp index 0a25f13d8..3ed0b20ea 100644 --- a/src/modulemanager.cpp +++ b/src/modulemanager.cpp @@ -222,6 +222,7 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u) for (auto &mods : EventHandlers) mods.push_back(m); + Serialize::CreateTypes(); m->Prioritize(); FOREACH_MOD(OnModuleLoad, (u, m)); diff --git a/src/serialize.cpp b/src/serialize.cpp index 91ffba34d..0e3a2d17d 100644 --- a/src/serialize.cpp +++ b/src/serialize.cpp @@ -38,14 +38,19 @@ void Serialize::RegisterTypes() static AutoKick::Type akick; static Memo::Type memo; static XLine::Type xline; + CreateTypes(); +} + +void Serialize::CreateTypes() +{ + for (const auto &[_, s_type] : Serialize::Type::GetTypes()) + s_type->Create(); } void Serialize::CheckTypes() { - for (const auto &[_, t] : Serialize::Type::GetTypes()) - { - t->Check(); - } + for (const auto &[_, s_type] : Serialize::Type::GetTypes()) + s_type->Check(); } Serializable::Serializable(const Anope::string &serialize_type) @@ -138,8 +143,6 @@ Type::Type(const Anope::string &n, Module *o) { TypeOrder.push_back(this->name); Types[this->name] = this; - - FOREACH_MOD(OnSerializeTypeCreate, (this)); } Type::~Type() @@ -160,6 +163,15 @@ Type::~Type() Types.erase(this->name); } +void Type::Create() +{ + if (created) + return; + + FOREACH_MOD(OnSerializeTypeCreate, (this)); + created = true; +} + void Type::Check() { FOREACH_MOD(OnSerializeCheck, (this));