diff options
| author | 2026-03-27 13:10:26 +0000 | |
|---|---|---|
| committer | 2026-03-27 13:10:26 +0000 | |
| commit | cbdcd051c63c4ff98dfb4ff45388e722f8d0a2de (patch) | |
| tree | f2c61a977edce634fc28b9dead3d8bfa5782211c | |
| parent | Move CUList to be declared inside User. (diff) | |
Switch the extensible system to using shared pointers.
| -rw-r--r-- | include/extensible.h | 5 | ||||
| -rw-r--r-- | include/extension.h | 135 | ||||
| -rw-r--r-- | include/modules/cap.h | 4 | ||||
| -rw-r--r-- | include/modules/geolocation.h | 7 | ||||
| -rw-r--r-- | include/modules/ssl.h | 9 | ||||
| -rw-r--r-- | modules/callerid.cpp | 37 | ||||
| -rw-r--r-- | modules/cap.cpp | 4 | ||||
| -rw-r--r-- | modules/cloak.cpp | 8 | ||||
| -rw-r--r-- | modules/cloak_custom.cpp | 5 | ||||
| -rw-r--r-- | modules/core/core_channel/invite.h | 33 | ||||
| -rw-r--r-- | modules/dccallow.cpp | 5 | ||||
| -rw-r--r-- | modules/extra/geo_maxmind.cpp | 69 | ||||
| -rw-r--r-- | modules/extra/ssl_gnutls.cpp | 2 | ||||
| -rw-r--r-- | modules/extra/ssl_openssl.cpp | 2 | ||||
| -rw-r--r-- | modules/geoban.cpp | 6 | ||||
| -rw-r--r-- | modules/geoclass.cpp | 6 | ||||
| -rw-r--r-- | modules/haproxy.cpp | 2 | ||||
| -rw-r--r-- | modules/ident.cpp | 3 | ||||
| -rw-r--r-- | modules/monitor.cpp | 24 | ||||
| -rw-r--r-- | modules/silence.cpp | 24 | ||||
| -rw-r--r-- | modules/spanningtree/hmac.cpp | 2 | ||||
| -rw-r--r-- | modules/sslinfo.cpp | 67 | ||||
| -rw-r--r-- | src/extensible.cpp | 89 |
23 files changed, 265 insertions, 283 deletions
diff --git a/include/extensible.h b/include/extensible.h index 4e299d7dc..797ec0ca7 100644 --- a/include/extensible.h +++ b/include/extensible.h @@ -24,6 +24,9 @@ class ExtensionItem; +/** A pointer to an extensible item. */ +using ExtensionPtr = std::shared_ptr<void>; + /** Types of extensible that an extension can extend. */ enum class ExtensionType : uint8_t @@ -44,7 +47,7 @@ class CoreExport Extensible { public: /** The container which extension values are stored in. */ - using ExtensibleStore = insp::flat_map<ExtensionItem*, void*>; + using ExtensibleStore = insp::flat_map<ExtensionItem*, ExtensionPtr>; /** Allows extensions to access the extension store. */ friend class ExtensionItem; diff --git a/include/extension.h b/include/extension.h index cff6ab878..b2b37ac66 100644 --- a/include/extension.h +++ b/include/extension.h @@ -30,12 +30,6 @@ public: /** The type of extensible that this extension extends. */ const ExtensionType extype:2; - /** Deletes a \p value which is set on \p container. - * @param container The container that this extension is set on. - * @param item The item to delete. - */ - virtual void Delete(Extensible* container, void* item) = 0; - /** Deserialises a value for this extension of the specified container from the internal format. * @param container A container this extension should be set on. * @param value A value in the internal format. @@ -48,12 +42,18 @@ public: */ virtual void FromNetwork(Extensible* container, const std::string& value) noexcept; + /** Called when a value for this extension is deleted. + * @param container The container that this extension is set on. + * @param item The value that is set on the container. + */ + virtual void OnDelete(const Extensible* container, const ExtensionPtr& item); + /** Called when a value for this extension is synchronised across the network. * @param container The container that this extension is set on. * @param item The value that is set on the container. * @param server The server which is being synchronised to or nullptr for a broadcast. */ - virtual void OnSync(const Extensible* container, void* item, Server* server); + virtual void OnSync(const Extensible* container, const ExtensionPtr& item, Server* server); /** @copydoc ServiceProvider::RegisterService */ void RegisterService() override; @@ -64,21 +64,21 @@ public: * @param item The value to convert to the human-readable format. * @return The value specified in \p item in the human-readable format. */ - virtual std::string ToHuman(const Extensible* container, void* item) const noexcept; + virtual std::string ToHuman(const Extensible* container, const ExtensionPtr& item) const noexcept; /** Serialises a value for this extension of the specified container to the internal format. * @param container The container that this extension is set on. * @param item The value to convert to the internal format. * @return The value specified in \p item in the internal format. */ - virtual std::string ToInternal(const Extensible* container, void* item) const noexcept; + virtual std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept; /** Serialises a value for this extension of the specified container to the network format. * @param container The container that this extension is set on. * @param item The value to convert to the network format. * @return The value specified in \p item in the network format. */ - virtual std::string ToNetwork(const Extensible* container, void* item) const noexcept; + virtual std::string ToNetwork(const Extensible* container, const ExtensionPtr& item) const noexcept; protected: /** Initializes an instance of the ExtensionItem class. @@ -92,7 +92,7 @@ protected: * @param container The container that this extension is set on. * @return Either the value of this extension or nullptr if it does not exist. */ - void* GetRaw(const Extensible* container) const; + const ExtensionPtr* GetRaw(const Extensible* container) const; /** Sets a value for this extension of the specified container in the internal map and * returns the old value if one was set @@ -100,20 +100,20 @@ protected: * @param value The new value to set for this extension. Will NOT be copied. * @return Either the old value or nullptr if one is not set. */ - void* SetRaw(Extensible* container, void* value); + ExtensionPtr SetRaw(Extensible* container, const ExtensionPtr& value); /** Syncs the value of this extension of the specified container across the network. Does * nothing if an inheritor does not implement ExtensionItem::ToNetwork. * @param container The container that this extension is set on. * @param item The value of this extension. */ - void Sync(const Extensible* container, void* item); + void Sync(const Extensible* container, const ExtensionPtr& item); /** Removes this extension from the specified container and returns it. * @param container The container that this extension should be removed from. * @return Either the old value of this extension or nullptr if it was not set. */ - void* UnsetRaw(Extensible* container); + ExtensionPtr UnsetRaw(Extensible* container); }; /** An extension which has a simple (usually POD) value. */ @@ -126,6 +126,9 @@ protected: bool synced; public: + /** The underlying pointer type. */ + using ValuePtr = std::shared_ptr<Value>; + /** Initializes an instance of the SimpleExtItem<T,Del> class. * @param owner The module which created the extension. * @param key The name of the extension (e.g. foo-bar). @@ -146,16 +149,19 @@ public: } /** @copydoc ExtensionItem::ToNetwork */ - std::string ToNetwork(const Extensible* container, void* item) const noexcept override + std::string ToNetwork(const Extensible* container, const ExtensionPtr& item) const noexcept override { return synced ? ToInternal(container, item) : std::string(); } - /** @copydoc ExtensionItem::Delete */ - void Delete(Extensible* container, void* item) override + /** Creates a new shared pointer with the deleter specified in the extension item. + * @param args The arguments to forward to the constructor of \p T. + */ + template <typename... Args> + ValuePtr Create(Args&&... args) { - Del del; - del(static_cast<Value*>(item)); + auto* ptr = new Value(std::forward<Args>(args)...); + return ValuePtr(ptr, Del()); } /** Retrieves the value for this extension of the specified container. @@ -164,7 +170,18 @@ public: */ inline Value* Get(const Extensible* container) const { - return static_cast<Value*>(GetRaw(container)); + auto* ptr = GetRaw(container); + return ptr ? std::static_pointer_cast<Value>(*ptr).get() : nullptr; + } + + /** Retrieves the value for this extension of the specified container. + * @param container The container that this extension is set on. + * @return A shared pointer to the value of this extension, empty if it is not set. + */ + inline ValuePtr GetPtr(const Extensible* container) const + { + auto* ptr = GetRaw(container); + return ptr ? ValuePtr() : std::static_pointer_cast<Value>(*ptr); } /** Retrieves the value for this extension of the specified container. @@ -173,13 +190,13 @@ public: */ inline Value& GetRef(Extensible* container) { - auto* value = Get(container); - if (!value) - { - value = new Value(); - Set(container, value, false); - } - return *value; + auto* ptr = GetRaw(container); + if (ptr) + return *std::static_pointer_cast<Value>(*ptr).get(); + + auto value = Create(); + Set(container, value, false); + return *value.get(); } /** Sets a value for this extension of the specified container. @@ -187,26 +204,37 @@ public: * @param value The new value to set for this extension. Will NOT be copied. * @param sync If syncable then whether to sync this set to the network. */ - inline void Set(Extensible* container, Value* value, bool sync = true) + inline void Set(Extensible* container, const ValuePtr& value, bool sync = true) { if (container->extype != this->extype) return; - auto old = static_cast<Value*>(SetRaw(container, value)); - Delete(container, old); + auto old = std::static_pointer_cast<Value>(SetRaw(container, value)); + OnDelete(container, old); if (sync && synced) Sync(container, value); } /** Sets a value for this extension of the specified container. * @param container The container that this extension should be set on. + * @param value The new value to set for this extension. Will NOT be copied. + * @param sync If syncable then whether to sync this set to the network. + */ + inline void Set(Extensible* container, Value* value, bool sync = true) + { + if (container->extype == this->extype) + Set(container, ValuePtr(value, Del()), sync); + } + + /** Sets a value for this extension of the specified container. + * @param container The container that this extension should be set on. * @param value The new value to set for this extension. Will be copied. * @param sync If syncable then whether to sync this set to the network. */ inline void Set(Extensible* container, const Value& value, bool sync = true) { if (container->extype == this->extype) - Set(container, new Value(value), sync); + Set(container, Create(value), sync); } /** Sets a forwarded value for this extension of the specified container. @@ -220,7 +248,7 @@ public: // be synced across the network. You can manually call Sync() if this // is not the case. if (container->extype == this->extype) - Set(container, new Value(std::forward<Args>(args)...), false); + Set(container, Create(std::forward<Args>(args)...), false); } /** Removes this extension from the specified container. @@ -232,7 +260,7 @@ public: if (container->extype != this->extype) return; - Delete(container, UnsetRaw(container)); + OnDelete(container, UnsetRaw(container)); if (synced && sync) Sync(container, nullptr); } @@ -255,9 +283,6 @@ public: */ BoolExtItem(Module* owner, const std::string& key, ExtensionType exttype, bool sync = false); - /** @copydoc ExtensionItem::Delete */ - void Delete(Extensible* container, void* item) override; - /** Retrieves the value for this extension of the specified container. * @param container The container that this extension is set on. * @return Either the value of this extension or false if it is not set. @@ -277,13 +302,13 @@ public: void Set(Extensible* container, bool sync = true); /** @copydoc ExtensionItem::ToHuman */ - std::string ToHuman(const Extensible* container, void* item) const noexcept override; + std::string ToHuman(const Extensible* container, const ExtensionPtr& item) const noexcept override; /** @copydoc ExtensionItem::ToInternal */ - std::string ToInternal(const Extensible* container, void* item) const noexcept override; + std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept override; /** @copydoc ExtensionItem::ToNetwork */ - std::string ToNetwork(const Extensible* container, void* item) const noexcept override; + std::string ToNetwork(const Extensible* container, const ExtensionPtr& item) const noexcept override; /** Removes this extension from the specified container. * @param container The container that this extension should be removed from. @@ -301,6 +326,9 @@ public: /** The underlying list type. */ using List = Container; + /** A pointer to the underlying list type. */ + using ListPtr = std::shared_ptr<List>; + /** Initializes an instance of the ListExtItem class. * @param owner The module which created the extension. * @param key The name of the extension (e.g. foo-bar). @@ -324,10 +352,13 @@ public: return; } - auto list = new List(); + ListPtr list; StringSplitter stream(value); for (std::string element; stream.GetToken(element); ) { + if (!list) + list = this->Create(); + // Argh! Why doesn't vector<string> have an insert(value_type) method? if constexpr (std::is_same_v<Container, std::vector<typename Container::value_type>>) list->push_back(Percent::Decode(element)); @@ -335,10 +366,9 @@ public: list->insert(Percent::Decode(element)); } - if (list->empty()) + if (!list) { // The remote sent an empty list. - delete list; SimpleExtItem<Container>::Unset(container, false); } else @@ -349,20 +379,20 @@ public: } /** @copydoc ExtensionItem::ToInternal */ - std::string ToHuman(const Extensible* container, void* item) const noexcept override + std::string ToHuman(const Extensible* container, const ExtensionPtr& item) const noexcept override { - auto list = static_cast<List*>(item); - if (list->empty()) + const auto& list = std::static_pointer_cast<List>(item); + if (!list || list->empty()) return {}; return insp::join(*list, ' '); } /** @copydoc ExtensionItem::ToInternal */ - std::string ToInternal(const Extensible* container, void* item) const noexcept override + std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept override { - auto list = static_cast<List*>(item); - if (list->empty()) + const auto& list = std::static_pointer_cast<List>(item); + if (!list || list->empty()) return {}; std::string value; @@ -391,9 +421,6 @@ public: */ IntExtItem(Module* owner, const std::string& key, ExtensionType exttype, bool sync = false); - /** @copydoc ExtensionItem::Delete */ - void Delete(Extensible* container, void* item) override; - /** Retrieves the value for this extension of the specified container. * @param container The container that this extension is set on. * @return Either the value of this extension or 0 if it is not set. @@ -414,10 +441,10 @@ public: void Set(Extensible* container, intptr_t value, bool sync = true); /** @copydoc ExtensionItem::ToInternal */ - std::string ToInternal(const Extensible* container, void* item) const noexcept override; + std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept override; /** @copydoc ExtensionItem::ToNetwork */ - std::string ToNetwork(const Extensible* container, void* item) const noexcept override; + std::string ToNetwork(const Extensible* container, const ExtensionPtr& item) const noexcept override; /** Removes this extension from the specified container. * @param container The container that this extension should be removed from. @@ -443,5 +470,5 @@ public: void FromInternal(Extensible* container, const std::string& value) noexcept override; /** @copydoc ExtensionItem::ToInternal */ - std::string ToInternal(const Extensible* container, void* item) const noexcept override; + std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept override; }; diff --git a/include/modules/cap.h b/include/modules/cap.h index 63d5f8c0b..d665f1509 100644 --- a/include/modules/cap.h +++ b/include/modules/cap.h @@ -34,8 +34,8 @@ namespace Cap public: ExtItem(Module* mod); void FromInternal(Extensible* container, const std::string& value) noexcept override; - std::string ToHuman(const Extensible* container, void* item) const noexcept override; - std::string ToInternal(const Extensible* container, void* item) const noexcept override; + std::string ToHuman(const Extensible* container, const ExtensionPtr& item) const noexcept override; + std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept override; }; class Capability; diff --git a/include/modules/geolocation.h b/include/modules/geolocation.h index b784f6531..fffc8489d 100644 --- a/include/modules/geolocation.h +++ b/include/modules/geolocation.h @@ -24,6 +24,8 @@ namespace Geolocation class APIBase; class API; class Location; + + using LocationPtr = std::shared_ptr<Location>; } class Geolocation::APIBase @@ -39,13 +41,13 @@ public: * @param user The user to look up the location of. * @return Either an instance of the Location class or NULL if no location could be found. */ - virtual Location* GetLocation(User* user) = 0; + virtual LocationPtr GetLocation(User* user) = 0; /** Looks up the location of the specified IP address. * @param sa The IP address to look up the location of. * @return Either an instance of the Location class or NULL if no location could be found. */ - virtual Location* GetLocation(irc::sockets::sockaddrs& sa) = 0; + virtual LocationPtr GetLocation(irc::sockets::sockaddrs& sa) = 0; }; class Geolocation::API final @@ -59,7 +61,6 @@ public: }; class Geolocation::Location final - : public usecountbase { private: /** The two character country code for this location. */ diff --git a/include/modules/ssl.h b/include/modules/ssl.h index 5cff540ea..e1649cc98 100644 --- a/include/modules/ssl.h +++ b/include/modules/ssl.h @@ -37,7 +37,6 @@ * connected local users using SSLCertExt */ class ssl_cert final - : public refcountbase { public: std::string dn; @@ -194,7 +193,7 @@ protected: /** Peer TLS certificate, set by the TLS module */ - reference<ssl_cert> certificate; + std::shared_ptr<ssl_cert> certificate; /** The status of the TLS connection. */ Status status = STATUS_NONE; @@ -246,7 +245,7 @@ public: * Get the certificate sent by this peer * @return The TLS certificate sent by the peer, NULL if no cert was sent */ - virtual ssl_cert* GetCertificate() const + virtual const std::shared_ptr<ssl_cert>& GetCertificate() const { return certificate; } @@ -258,7 +257,7 @@ public: */ virtual std::string GetFingerprint() const { - ssl_cert* cert = GetCertificate(); + const auto& cert = GetCertificate(); if (cert && cert->IsUsable()) return cert->GetFingerprint(); return ""; @@ -304,7 +303,7 @@ public: * @param user The user whose certificate to set. * @param cert The TLS certificate to set for the user. */ - virtual void SetCertificate(User* user, ssl_cert* cert) = 0; + virtual void SetCertificate(User* user, const std::shared_ptr<ssl_cert>& cert) = 0; /** Get the primary fingerprint from a user's certificate * @param user The user whose primary fingerprint to get. diff --git a/modules/callerid.cpp b/modules/callerid.cpp index 23410a594..f89b1e9aa 100644 --- a/modules/callerid.cpp +++ b/modules/callerid.cpp @@ -85,15 +85,15 @@ struct CallerIDExtInfo final { } - std::string ToHuman(const Extensible* container, void* item) const noexcept override + std::string ToHuman(const Extensible* container, const ExtensionPtr& item) const noexcept override { - callerid_data* dat = static_cast<callerid_data*>(item); + const auto& dat = std::static_pointer_cast<callerid_data>(item); return dat->ToString(true); } - std::string ToInternal(const Extensible* container, void* item) const noexcept override + std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept override { - callerid_data* dat = static_cast<callerid_data*>(item); + const auto& dat = std::static_pointer_cast<callerid_data>(item); return dat->ToString(false); } @@ -102,10 +102,11 @@ struct CallerIDExtInfo final if (container->extype != this->extype) return; - void* old = GetRaw(container); + auto* old = GetRaw(container); if (old) - this->Delete(nullptr, old); - auto* dat = new callerid_data(); + this->OnDelete(container, *old); + + auto dat = std::make_shared<callerid_data>(); SetRaw(container, dat); StringSplitter s(value, ','); @@ -119,7 +120,7 @@ struct CallerIDExtInfo final if (dat->accepting.insert(u).second) { callerid_data* other = this->Get(u, true); - other->wholistsme.push_back(dat); + other->wholistsme.push_back(dat.get()); } } } @@ -127,18 +128,21 @@ struct CallerIDExtInfo final callerid_data* Get(User* user, bool create) { - callerid_data* dat = static_cast<callerid_data*>(GetRaw(user)); - if (create && !dat) + auto* dat = GetRaw(user); + if (!dat) { - dat = new callerid_data; - SetRaw(user, dat); + if (!create) + return nullptr; + + SetRaw(user, std::make_shared<callerid_data>()); + dat = GetRaw(user); } - return dat; + return std::static_pointer_cast<callerid_data>(*dat).get(); } - void Delete(Extensible* container, void* item) override + void OnDelete(const Extensible* container, const ExtensionPtr& item) override { - callerid_data* dat = static_cast<callerid_data*>(item); + const auto& dat = std::static_pointer_cast<callerid_data>(item); // We need to walk the list of users on our accept list, and remove ourselves from their wholistsme. for (auto* user : dat->accepting) @@ -150,10 +154,9 @@ struct CallerIDExtInfo final continue; // shouldn't happen, but oh well. } - if (!stdalgo::vector::swaperase(target->wholistsme, dat)) + if (!stdalgo::vector::swaperase(target->wholistsme, dat.get())) ServerInstance->Logs.Debug(MODNAME, "BUG: Inconsistency detected in callerid state, please report (2)"); } - delete dat; } }; diff --git a/modules/cap.cpp b/modules/cap.cpp index 7a34af4dd..0835847ab 100644 --- a/modules/cap.cpp +++ b/modules/cap.cpp @@ -318,12 +318,12 @@ Cap::ExtItem::ExtItem(Module* mod) { } -std::string Cap::ExtItem::ToHuman(const Extensible* container, void* item) const noexcept +std::string Cap::ExtItem::ToHuman(const Extensible* container, const ExtensionPtr& item) const noexcept { return SerializeCaps(container, true); } -std::string Cap::ExtItem::ToInternal(const Extensible* container, void* item) const noexcept +std::string Cap::ExtItem::ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept { return SerializeCaps(container, false); } diff --git a/modules/cloak.cpp b/modules/cloak.cpp index df903b28f..5c1a94b75 100644 --- a/modules/cloak.cpp +++ b/modules/cloak.cpp @@ -110,9 +110,9 @@ public: } } - std::string ToHuman(const Extensible* container, void* item) const noexcept override + std::string ToHuman(const Extensible* container, const ExtensionPtr& item) const noexcept override { - auto* cloaks = static_cast<Cloak::List*>(item); + const auto& cloaks = std::static_pointer_cast<Cloak::List>(item); if (cloaks->empty()) return {}; @@ -124,9 +124,9 @@ public: return value; } - std::string ToInternal(const Extensible* container, void* item) const noexcept override + std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept override { - auto* cloaks = static_cast<Cloak::List*>(item); + const auto& cloaks = std::static_pointer_cast<Cloak::List>(item); if (cloaks->empty()) return {}; diff --git a/modules/cloak_custom.cpp b/modules/cloak_custom.cpp index 1ca666797..70a68cf0b 100644 --- a/modules/cloak_custom.cpp +++ b/modules/cloak_custom.cpp @@ -67,9 +67,10 @@ public: } } - std::string ToInternal(const Extensible* container, void* item) const noexcept override + std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept override { - return item ? Percent::Encode(static_cast<Cloak::Info*>(item)->ToString()) : std::string(); + const auto& cloak = std::static_pointer_cast<Cloak::Info>(item); + return cloak ? Percent::Encode(cloak->ToString()) : std::string(); } }; diff --git a/modules/core/core_channel/invite.h b/modules/core/core_channel/invite.h index 2313f191f..cebef5a94 100644 --- a/modules/core/core_channel/invite.h +++ b/modules/core/core_channel/invite.h @@ -49,10 +49,10 @@ class Invite::ExtItem final : public ExtensionItem { private: - static std::string ToString(void* item, bool human) + static std::string ToString(const ExtensionPtr& item, bool human) { std::string ret; - Store<T>* store = static_cast<Store<T>*>(item); + const auto& store = std::static_pointer_cast<Store<T>>(item); for (auto* inv : store->invites) inv->Serialize(human, (ExtType == ExtensionType::USER), ret); @@ -70,42 +70,43 @@ public: Store<T>* Get(Extensible* ext, bool create = false) { - Store<T>* store = static_cast<Store<T>*>(GetRaw(ext)); - if ((create) && (!store)) + auto* store = GetRaw(ext); + if (!store) { - store = new Store<T>; - SetRaw(ext, store); + if (!create) + return nullptr; + + SetRaw(ext, std::make_shared<Store<T>>()); + store = GetRaw(ext); } - return store; + return std::static_pointer_cast<Store<T>>(*store).get(); } void Unset(Extensible* ext) { - void* store = UnsetRaw(ext); + auto store = UnsetRaw(ext); if (store) - Delete(ext, store); + OnDelete(ext, store); } - void Delete(Extensible* container, void* item) override + void OnDelete(const Extensible* container, const ExtensionPtr& item) override { - Store<T>* store = static_cast<Store<T>*>(item); - for (typename Store<T>::List::iterator i = store->invites.begin(); i != store->invites.end(); ) + const auto& store = std::static_pointer_cast<Store<T>>(item); + for (auto i = store->invites.begin(); i != store->invites.end(); ) { Invite* inv = *i; // Destructing the Invite invalidates the iterator, so move it now ++i; RemoveInvite(inv, (ExtType != ExtensionType::USER), (ExtType == ExtensionType::USER)); } - - delete store; } - std::string ToHuman(const Extensible* container, void* item) const noexcept override + std::string ToHuman(const Extensible* container, const ExtensionPtr& item) const noexcept override { return ToString(item, true); } - std::string ToInternal(const Extensible* container, void* item) const noexcept override + std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept override { return ToString(item, false); } diff --git a/modules/dccallow.cpp b/modules/dccallow.cpp index f52e16851..f17919f75 100644 --- a/modules/dccallow.cpp +++ b/modules/dccallow.cpp @@ -168,9 +168,10 @@ public: Set(user, list); } - std::string ToInternal(const Extensible* container, void* item) const noexcept override + std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept override { - auto* list = static_cast<dccallowlist*>(item); + const auto& list = std::static_pointer_cast<dccallowlist>(item); + std::string buf; for (const auto& entry : *list) { diff --git a/modules/extra/geo_maxmind.cpp b/modules/extra/geo_maxmind.cpp index 3b1b8f73e..b43ae3072 100644 --- a/modules/extra/geo_maxmind.cpp +++ b/modules/extra/geo_maxmind.cpp @@ -34,45 +34,22 @@ #include "modules/geolocation.h" class GeolocationExtItem final - : public ExtensionItem + : public SimpleExtItem<Geolocation::Location> { public: - GeolocationExtItem(Module* parent) - : ExtensionItem(parent, "geolocation", ExtensionType::USER) + GeolocationExtItem(Module* mod) + : SimpleExtItem<Geolocation::Location>(mod, "geolocation", ExtensionType::USER) { } - std::string ToHuman(const Extensible* container, void* item) const noexcept override + std::string ToHuman(const Extensible* container, const ExtensionPtr& item) const noexcept override { - Geolocation::Location* location = static_cast<Geolocation::Location*>(item); + const auto& location = std::static_pointer_cast<Geolocation::Location>(item); return location->GetName() + " [" + location->GetCode() + "]"; } - - void Delete(Extensible* container, void* item) override - { - Geolocation::Location* old = static_cast<Geolocation::Location*>(item); - if (old) - old->refcount_dec(); - } - - Geolocation::Location* Get(const User* user) const - { - return static_cast<Geolocation::Location*>(GetRaw(user)); - } - - void Set(User* user, Geolocation::Location* value) - { - value->refcount_inc(); - Delete(user, SetRaw(user, value)); - } - - void Unset(User* user) - { - Delete(user, UnsetRaw(user)); - } }; -using LocationMap = insp::flat_map<std::string, Geolocation::Location*>; +using LocationMap = insp::flat_map<std::string, std::weak_ptr<Geolocation::Location>>; class GeolocationAPIImpl final : public Geolocation::APIBase @@ -88,11 +65,11 @@ public: { } - Geolocation::Location* GetLocation(User* user) override + Geolocation::LocationPtr GetLocation(User* user) override { // If we have the location cached then use that instead. - Geolocation::Location* location = ext.Get(user); - if (location) + auto location = ext.GetPtr(user); + if (!location) return location; // Attempt to locate this user. @@ -105,7 +82,7 @@ public: return location; } - Geolocation::Location* GetLocation(irc::sockets::sockaddrs& sa) override + Geolocation::LocationPtr GetLocation(irc::sockets::sockaddrs& sa) override { // Skip trying to look up a UNIX socket. if (!sa.is_ip()) @@ -127,7 +104,11 @@ public: const std::string code(country_code.utf8_string, country_code.data_size); LocationMap::iterator liter = locations.find(code); if (liter != locations.end()) - return liter->second; + { + auto ptr = liter->second.lock(); + if (ptr) + return ptr; // We have a country already. + } // Attempt to retrieve the country name. MMDB_entry_data_s country_name; @@ -137,7 +118,7 @@ public: // Create a Location object and cache it. const std::string cname(country_name.utf8_string, country_name.data_size); - auto* location = new Geolocation::Location(code, cname); + auto location = std::make_shared<Geolocation::Location>(code, cname); locations[code] = location; return location; } @@ -192,20 +173,16 @@ public: { for (LocationMap::iterator iter = geoapi.locations.begin(); iter != geoapi.locations.end(); ) { - Geolocation::Location* location = iter->second; - if (location->GetUseCount()) - { - ServerInstance->Logs.Debug(MODNAME, "Preserving geolocation data for {} ({}) with use count {}... ", - location->GetName(), location->GetCode(), location->GetUseCount()); - iter++; - } - else + auto location = iter->second.lock(); + if (!location) { - ServerInstance->Logs.Debug(MODNAME, "Deleting unused geolocation data for {} ({})", - location->GetName(), location->GetCode()); - delete location; iter = geoapi.locations.erase(iter); + continue; // Entry expired. } + + ServerInstance->Logs.Debug(MODNAME, "Preserving geolocation data for {} ({}) with use count {}... ", + location->GetName(), location->GetCode(), location.use_count()); + iter++; } geoapi.locations.shrink_to_fit(); } diff --git a/modules/extra/ssl_gnutls.cpp b/modules/extra/ssl_gnutls.cpp index 0b976fad5..9602b5728 100644 --- a/modules/extra/ssl_gnutls.cpp +++ b/modules/extra/ssl_gnutls.cpp @@ -653,7 +653,7 @@ private: void VerifyCertificate() { - auto* certinfo = new ssl_cert(); + auto certinfo = std::make_shared<ssl_cert>(); this->certificate = certinfo; unsigned int certstatus; diff --git a/modules/extra/ssl_openssl.cpp b/modules/extra/ssl_openssl.cpp index 96b4f8c09..4c3a736e7 100644 --- a/modules/extra/ssl_openssl.cpp +++ b/modules/extra/ssl_openssl.cpp @@ -548,7 +548,7 @@ private: void VerifyCertificate() { - auto* certinfo = new ssl_cert(); + auto certinfo = std::make_shared<ssl_cert>(); this->certificate = certinfo; auto* cert = SSL_get1_peer_certificate(sess); diff --git a/modules/geoban.cpp b/modules/geoban.cpp index 125a522b1..ff64bcf6c 100644 --- a/modules/geoban.cpp +++ b/modules/geoban.cpp @@ -39,7 +39,7 @@ public: bool IsMatch(ListModeBase* lm, User* user, Channel* channel, const std::string& text, const ExtBan::MatchConfig& config) override { - Geolocation::Location* location = geoapi ? geoapi->GetLocation(user) : nullptr; + const auto location = geoapi ? geoapi->GetLocation(user) : nullptr; const std::string code = location ? location->GetCode() : "XX"; // Does this user match against the ban? @@ -71,7 +71,7 @@ public: if (!request.flags['G']) return MOD_RES_PASSTHRU; - Geolocation::Location* location = geoapi ? geoapi->GetLocation(user) : nullptr; + const auto location = geoapi ? geoapi->GetLocation(user) : nullptr; const std::string code = location ? location->GetCode() : "XX"; return InspIRCd::Match(code, request.matchtext, ascii_case_insensitive_map) ? MOD_RES_ALLOW : MOD_RES_DENY; } @@ -81,7 +81,7 @@ public: if (whois.GetTarget()->server->IsService()) return; - Geolocation::Location* location = geoapi ? geoapi->GetLocation(whois.GetTarget()) : nullptr; + const auto location = geoapi ? geoapi->GetLocation(whois.GetTarget()) : nullptr; if (location) whois.SendLine(RPL_WHOISCOUNTRY, location->GetCode(), "is connecting from " + location->GetName()); else diff --git a/modules/geoclass.cpp b/modules/geoclass.cpp index 0ca587036..4cfcc62d2 100644 --- a/modules/geoclass.cpp +++ b/modules/geoclass.cpp @@ -46,7 +46,7 @@ public: // If we can't find the location of this user then we can't assign // them to a location-specific connect class. - Geolocation::Location* location = geoapi ? geoapi->GetLocation(user) : nullptr; + const auto location = geoapi ? geoapi->GetLocation(user) : nullptr; const std::string code = location ? location->GetCode() : "XX"; StringSplitter codes(country); @@ -78,14 +78,14 @@ public: return MOD_RES_PASSTHRU; // Counter for the number of users in each country. - std::map<Geolocation::Location*, size_t> counts; + std::map<Geolocation::LocationPtr, size_t> counts; // Counter for the number of users in an unknown country. size_t unknown = 0; for (auto* user : ServerInstance->Users.GetLocalUsers()) { - Geolocation::Location* location = geoapi ? geoapi->GetLocation(user) : nullptr; + const auto location = geoapi ? geoapi->GetLocation(user) : nullptr; if (location) counts[location]++; else diff --git a/modules/haproxy.cpp b/modules/haproxy.cpp index 20159b89a..c6eff4a34 100644 --- a/modules/haproxy.cpp +++ b/modules/haproxy.cpp @@ -210,7 +210,7 @@ private: // Create a fake ssl_cert for the user. Ideally we should use the user's // TLS client certificate here but as of 2018-10-16 this is not forwarded // by HAProxy. - auto* cert = new ssl_cert(); + auto cert = std::make_shared<ssl_cert>(); cert->error = "HAProxy does not forward client TLS certificates"; cert->invalid = true; cert->revoked = true; diff --git a/modules/ident.cpp b/modules/ident.cpp index 97e504e83..da84227c2 100644 --- a/modules/ident.cpp +++ b/modules/ident.cpp @@ -342,8 +342,7 @@ public: try { - isock = new IdentRequestSocket(this, user); - socket.Set(user, isock); + socket.SetFwd(user, this, user); } catch (const ModuleException& e) { diff --git a/modules/monitor.cpp b/modules/monitor.cpp index 5255c79b2..9c14db837 100644 --- a/modules/monitor.cpp +++ b/modules/monitor.cpp @@ -74,24 +74,27 @@ class IRCv3::Monitor::Manager final ExtData* Get(User* user, bool create = false) { - ExtData* extdata = static_cast<ExtData*>(GetRaw(user)); - if ((!extdata) && (create)) + auto* extdata = GetRaw(user); + if (!extdata) { - extdata = new ExtData; - SetRaw(user, extdata); + if (!create) + return nullptr; + + SetRaw(user, std::make_shared<ExtData>()); + extdata = GetRaw(user); } - return extdata; + return std::static_pointer_cast<ExtData>(*extdata).get(); } void Unset(User* user) { - Delete(user, UnsetRaw(user)); + OnDelete(user, UnsetRaw(user)); } - std::string ToInternal(const Extensible* container, void* item) const noexcept override + std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept override { std::string ret; - const ExtData* extdata = static_cast<ExtData*>(item); + const auto& extdata = std::static_pointer_cast<ExtData>(item); for (const auto* entry : extdata->list) ret.append(entry->GetNick()).push_back(' '); if (!ret.empty()) @@ -100,11 +103,6 @@ class IRCv3::Monitor::Manager final } void FromInternal(Extensible* container, const std::string& value) noexcept override; - - void Delete(Extensible* container, void* item) override - { - delete static_cast<ExtData*>(item); - } }; public: diff --git a/modules/silence.cpp b/modules/silence.cpp index 996535673..1ce7d6c67 100644 --- a/modules/silence.cpp +++ b/modules/silence.cpp @@ -224,7 +224,7 @@ public: // Remove the old list and create a new one. Unset(user, false); - SilenceList* list = nullptr; + std::shared_ptr<SilenceList> list; StringSplitter ts(value); while (!ts.AtEnd()) @@ -234,7 +234,6 @@ public: { ServerInstance->Logs.Debug(MODNAME, "Oversized silence list received for {}: {}", user->uuid, value); - delete list; return; } @@ -245,7 +244,6 @@ public: { ServerInstance->Logs.Debug(MODNAME, "Malformed silence list received for {}: {}", user->uuid, value); - delete list; return; } @@ -255,13 +253,12 @@ public: { ServerInstance->Logs.Debug(MODNAME, "Malformed silence flags received for {}: {}", user->uuid, flagstr); - delete list; return; } // Store the silence entry. if (!list) - list = new SilenceList(); + list = std::make_shared<SilenceList>(); list->emplace(flags, mask); } @@ -270,9 +267,10 @@ public: Set(user, list, false); } - std::string ToInternal(const Extensible* container, void* item) const noexcept override + std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept override { - auto* list = static_cast<SilenceList*>(item); + const auto& list = std::static_pointer_cast<SilenceList>(item); + std::string buf; for (const auto& entry : *list) { @@ -307,20 +305,14 @@ private: CmdResult AddSilence(LocalUser* user, const std::string& mask, uint32_t flags) { - SilenceList* list = ext.Get(user); - if (list && list->size() > ext.maxsilence) + auto& list = ext.GetRef(user); + if (!list.empty() && list.size() > ext.maxsilence) { user->WriteNumeric(ERR_SILELISTFULL, mask, SilenceEntry::BitsToFlags(flags), "Your SILENCE list is full"); return CmdResult::FAILURE; } - else if (!list) - { - // There is no list; create it. - list = new SilenceList(); - ext.Set(user, list); - } - if (!list->emplace(flags, mask).second) + if (!list.emplace(flags, mask).second) { user->WriteNumeric(ERR_SILENCE, mask, SilenceEntry::BitsToFlags(flags), "The SILENCE entry you specified already exists"); return CmdResult::FAILURE; diff --git a/modules/spanningtree/hmac.cpp b/modules/spanningtree/hmac.cpp index 4a97bddbb..5dc8bd03d 100644 --- a/modules/spanningtree/hmac.cpp +++ b/modules/spanningtree/hmac.cpp @@ -74,7 +74,7 @@ bool TreeSocket::ComparePass(const Link& link, const std::string& theirs) capab->auth_challenge = !capab->ourchallenge.empty() && !capab->theirchallenge.empty(); const auto* sslhook = SSLIOHook::IsSSL(this); - const auto* sslcert = sslhook ? sslhook->GetCertificate() : nullptr; + const auto& sslcert = sslhook ? sslhook->GetCertificate() : nullptr; const auto sslcert_usable = sslcert && sslcert->IsUsable(); const auto fp = sslcert_usable ? sslcert->GetFingerprint() : ""; if (capab->auth_fingerprint) diff --git a/modules/sslinfo.cpp b/modules/sslinfo.cpp index 6916707bf..f1c26baa2 100644 --- a/modules/sslinfo.cpp +++ b/modules/sslinfo.cpp @@ -38,35 +38,14 @@ #include "timeutils.h" class SSLCertExt final - : public ExtensionItem + : public SimpleExtItem<ssl_cert> { public: - SSLCertExt(Module* parent) - : ExtensionItem(parent, "ssl_cert", ExtensionType::USER) + SSLCertExt(Module* mod) + : SimpleExtItem<ssl_cert>(mod, "ssl_cert", ExtensionType::USER) { } - ssl_cert* Get(const User* user) const - { - return static_cast<ssl_cert*>(GetRaw(user)); - } - - void Set(User* user, ssl_cert* value, bool sync = true) - { - value->refcount_inc(); - ssl_cert* old = static_cast<ssl_cert*>(SetRaw(user, value)); - if (old && old->refcount_dec()) - delete old; - - if (sync) - Sync(user, value); - } - - void Unset(User* user) - { - Delete(user, UnsetRaw(user)); - } - static std::string GetFlags(const ssl_cert* cert) { std::string ret; @@ -78,16 +57,12 @@ public: return ret; } - std::string ToInternal(const Extensible* container, void* item) const noexcept override + std::string ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept override { - return ToNetwork(container, item); - } + const auto& cert = std::static_pointer_cast<ssl_cert>(item); - std::string ToNetwork(const Extensible* container, void* item) const noexcept override - { - const ssl_cert* cert = static_cast<ssl_cert*>(item); std::stringstream value; - value << GetFlags(cert) << " "; + value << GetFlags(cert.get()) << " "; if (cert->GetError().empty()) value << insp::join(cert->GetFingerprints(), ',') << " " << cert->GetDN() << " " << cert->GetIssuer(); @@ -99,16 +74,11 @@ public: void FromInternal(Extensible* container, const std::string& value) noexcept override { - FromNetwork(container, value); - } - - void FromNetwork(Extensible* container, const std::string& value) noexcept override - { if (container->extype != this->extype) return; - auto* cert = new ssl_cert(); - Set(static_cast<User*>(container), cert, false); + auto cert = std::make_shared<ssl_cert>(); + Set(container, cert, false); std::stringstream s(value); std::string v; @@ -134,13 +104,6 @@ public: getline(s, cert->issuer, '\n'); } } - - void Delete(Extensible* container, void* item) override - { - ssl_cert* old = static_cast<ssl_cert*>(item); - if (old && old->refcount_dec()) - delete old; - } }; class UserCertificateAPIImpl final @@ -172,11 +135,13 @@ public: if (!ssliohook) return nullptr; - cert = ssliohook->GetCertificate(); - if (!cert) - return nullptr; + auto newcert = ssliohook->GetCertificate(); + if (newcert) + { + SetCertificate(user, newcert); + cert = newcert.get(); + } - SetCertificate(user, cert); return cert; } @@ -192,7 +157,7 @@ public: return false; } - void SetCertificate(User* user, ssl_cert* cert) override + void SetCertificate(User* user, const std::shared_ptr<ssl_cert>& cert) override { ServerInstance->Logs.Debug(MODNAME, "Setting TLS client certificate for {}: {}", user->GetMask(), sslext.ToNetwork(user, cert)); @@ -557,7 +522,7 @@ public: } // Create a fake ssl_cert for the user. - auto* cert = new ssl_cert(); + auto cert = std::make_shared<ssl_cert>(); cert->dn = "(unknown)"; cert->invalid = false; cert->issuer = "(unknown)"; diff --git a/src/extensible.cpp b/src/extensible.cpp index d69ae5794..584a44dd7 100644 --- a/src/extensible.cpp +++ b/src/extensible.cpp @@ -20,6 +20,23 @@ #include "inspircd.h" #include "extension.h" +namespace +{ + // These templates are used by BoolExtItem and IntExtItem to allow storing a + // value within the pointer address of a shared pointer. + template <typename T> + ExtensionPtr CreateFakePointer(T value) + { + return ExtensionPtr(reinterpret_cast<void*>(value), [](auto*) { }); + } + + template <typename T> + T GetFakePointer(const ExtensionPtr* ptr) + { + return ptr ? reinterpret_cast<T>(ptr->get()) : T(); + } +} + bool ExtensionManager::Register(ExtensionItem* item) { return types.emplace(item->service_name, item).second; @@ -73,7 +90,7 @@ Cullable::Result Extensible::Cull() void Extensible::FreeAllExtItems() { for (const auto& [extension, item] : extensions) - extension->Delete(this, item); + extension->OnDelete(this, item); extensions.clear(); } @@ -84,7 +101,7 @@ void Extensible::UnhookExtensions(const std::vector<ExtensionItem*>& items) ExtensibleStore::iterator iter = extensions.find(item); if (iter != extensions.end()) { - item->Delete(this, iter->second); + item->OnDelete(this, iter->second); extensions.erase(iter); } } @@ -96,7 +113,11 @@ ExtensionItem::ExtensionItem(Module* mod, const std::string& Key, ExtensionType { } -void ExtensionItem::OnSync(const Extensible* container, void* item, Server* server) +void ExtensionItem::OnDelete(const Extensible* container, const ExtensionPtr& item) +{ +} + +void ExtensionItem::OnSync(const Extensible* container, const ExtensionPtr& item, Server* server) { } @@ -106,38 +127,38 @@ void ExtensionItem::RegisterService() throw ModuleException(this->service_creator, "Extension already exists: {}", this->service_name); } -void* ExtensionItem::GetRaw(const Extensible* container) const +const ExtensionPtr* ExtensionItem::GetRaw(const Extensible* container) const { auto iter = container->extensions.find(const_cast<ExtensionItem*>(this)); if (iter == container->extensions.end()) return nullptr; - return iter->second; + return &iter->second; } -void* ExtensionItem::SetRaw(Extensible* container, void* value) +ExtensionPtr ExtensionItem::SetRaw(Extensible* container, const ExtensionPtr& value) { auto result = container->extensions.emplace(this, value); if (result.second) return nullptr; - void* old = result.first->second; + auto old = result.first->second; result.first->second = value; return old; } -void* ExtensionItem::UnsetRaw(Extensible* container) +ExtensionPtr ExtensionItem::UnsetRaw(Extensible* container) { auto iter = container->extensions.find(this); if (iter == container->extensions.end()) return nullptr; - void* result = iter->second; + auto result = iter->second; container->extensions.erase(iter); return result; } -void ExtensionItem::Sync(const Extensible* container, void* item) +void ExtensionItem::Sync(const Extensible* container, const ExtensionPtr& item) { const std::string networkstr = item ? ToNetwork(container, item) : ""; ServerInstance->PI->SendMetadata(container, this->service_name, networkstr); @@ -152,7 +173,7 @@ void ExtensionItem::FromNetwork(Extensible* container, const std::string& value) { } -std::string ExtensionItem::ToHuman(const Extensible* container, void* item) const noexcept +std::string ExtensionItem::ToHuman(const Extensible* container, const ExtensionPtr& item) const noexcept { // Try to use the network form by default. std::string ret = ToNetwork(container, item); @@ -164,12 +185,12 @@ std::string ExtensionItem::ToHuman(const Extensible* container, void* item) cons return ret; } -std::string ExtensionItem::ToInternal(const Extensible* container, void* item) const noexcept +std::string ExtensionItem::ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept { return {}; } -std::string ExtensionItem::ToNetwork(const Extensible* container, void* item) const noexcept +std::string ExtensionItem::ToNetwork(const Extensible* container, const ExtensionPtr& item) const noexcept { return {}; } @@ -180,11 +201,6 @@ BoolExtItem::BoolExtItem(Module* owner, const std::string& key, ExtensionType ex { } -void BoolExtItem::Delete(Extensible* container, void* item) -{ - // Intentionally left blank. -} - void BoolExtItem::FromInternal(Extensible* container, const std::string& value) noexcept { if (ConvToNum<intptr_t>(value)) @@ -193,7 +209,7 @@ void BoolExtItem::FromInternal(Extensible* container, const std::string& value) Unset(container, false); } -std::string BoolExtItem::ToHuman(const Extensible* container, void* item) const noexcept +std::string BoolExtItem::ToHuman(const Extensible* container, const ExtensionPtr& item) const noexcept { return item ? "set" : "unset"; } @@ -204,12 +220,12 @@ void BoolExtItem::FromNetwork(Extensible* container, const std::string& value) n FromInternal(container, value); } -std::string BoolExtItem::ToInternal(const Extensible* container, void* item) const noexcept +std::string BoolExtItem::ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept { return ConvToStr(!!item); } -std::string BoolExtItem::ToNetwork(const Extensible* container, void* item) const noexcept +std::string BoolExtItem::ToNetwork(const Extensible* container, const ExtensionPtr& item) const noexcept { return synced ? ToInternal(container, item) : std::string(); } @@ -224,9 +240,10 @@ void BoolExtItem::Set(Extensible* container, bool sync) if (container->extype != this->extype) return; - SetRaw(container, reinterpret_cast<void*>(1)); + auto ptr = CreateFakePointer(1); + SetRaw(container, ptr); if (sync && synced) - Sync(container, reinterpret_cast<void*>(1)); + Sync(container, ptr); } void BoolExtItem::Unset(Extensible* container, bool sync) @@ -236,7 +253,7 @@ void BoolExtItem::Unset(Extensible* container, bool sync) UnsetRaw(container); if (sync && synced) - Sync(container, reinterpret_cast<void*>(0)); + Sync(container, CreateFakePointer(0)); } IntExtItem::IntExtItem(Module* owner, const std::string& key, ExtensionType exttype, bool sync) @@ -245,11 +262,6 @@ IntExtItem::IntExtItem(Module* owner, const std::string& key, ExtensionType extt { } -void IntExtItem::Delete(Extensible* container, void* item) -{ - // Intentionally left blank. -} - void IntExtItem::FromInternal(Extensible* container, const std::string& value) noexcept { Set(container, ConvToNum<intptr_t>(value), false); @@ -263,7 +275,7 @@ void IntExtItem::FromNetwork(Extensible* container, const std::string& value) no intptr_t IntExtItem::Get(const Extensible* container) const { - return reinterpret_cast<intptr_t>(GetRaw(container)); + return GetFakePointer<intptr_t>(GetRaw(container)); } void IntExtItem::Set(Extensible* container, intptr_t value, bool sync) @@ -272,20 +284,23 @@ void IntExtItem::Set(Extensible* container, intptr_t value, bool sync) return; if (value) - SetRaw(container, reinterpret_cast<void*>(value)); + SetRaw(container, CreateFakePointer(value)); else UnsetRaw(container); if (sync && synced) - Sync(container, GetRaw(container)); + { + auto* ptr = GetRaw(container); + Sync(container, ptr ? *ptr : nullptr); + } } -std::string IntExtItem::ToInternal(const Extensible* container, void* item) const noexcept +std::string IntExtItem::ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept { - return ConvToStr(reinterpret_cast<intptr_t>(item)); + return ConvToStr(GetFakePointer<intptr_t>(&item)); } -std::string IntExtItem::ToNetwork(const Extensible* container, void* item) const noexcept +std::string IntExtItem::ToNetwork(const Extensible* container, const ExtensionPtr& item) const noexcept { return synced ? ToInternal(container, item) : std::string(); } @@ -314,8 +329,8 @@ void StringExtItem::FromInternal(Extensible* container, const std::string& value } -std::string StringExtItem::ToInternal(const Extensible* container, void* item) const noexcept +std::string StringExtItem::ToInternal(const Extensible* container, const ExtensionPtr& item) const noexcept { - return item ? *static_cast<std::string*>(item) : std::string(); + return item ? *std::static_pointer_cast<std::string>(item) : std::string(); } |
