diff options
| author | 2022-01-07 17:12:42 +0000 | |
|---|---|---|
| committer | 2022-01-07 17:16:50 +0000 | |
| commit | 52cc8a418307ae7a551d23e6bd2d367b544e7bf9 (patch) | |
| tree | 9fff020964190f33174e78ff6201381be577d0b3 /src/modules | |
| parent | Merge branch 'insp3' into master. (diff) | |
| download | inspircd++-52cc8a418307ae7a551d23e6bd2d367b544e7bf9.tar.gz inspircd++-52cc8a418307ae7a551d23e6bd2d367b544e7bf9.tar.bz2 inspircd++-52cc8a418307ae7a551d23e6bd2d367b544e7bf9.zip | |
Refactor CoreException and ModuleException.
Diffstat (limited to 'src/modules')
41 files changed, 150 insertions, 128 deletions
diff --git a/src/modules/extra/m_argon2.cpp b/src/modules/extra/m_argon2.cpp index 2a5341cd8..80289286e 100644 --- a/src/modules/extra/m_argon2.cpp +++ b/src/modules/extra/m_argon2.cpp @@ -144,7 +144,7 @@ class HashArgon2 final config.version); if (argonResult != ARGON2_OK) - throw ModuleException("Argon2 hashing failed!: " + std::string(argon2_error_message(argonResult))); + throw ModuleException(creator, "Argon2 hashing failed: " + std::string(argon2_error_message(argonResult))); // This isn't the raw version, but we don't have // the facilities to juggle around the extra state required diff --git a/src/modules/extra/m_geo_maxmind.cpp b/src/modules/extra/m_geo_maxmind.cpp index 56ccffef5..bff8c4b78 100644 --- a/src/modules/extra/m_geo_maxmind.cpp +++ b/src/modules/extra/m_geo_maxmind.cpp @@ -173,7 +173,7 @@ class ModuleGeoMaxMind final MMDB_s mmdb; int result = MMDB_open(file.c_str(), MMDB_MODE_MMAP, &mmdb); if (result != MMDB_SUCCESS) - throw ModuleException(InspIRCd::Format("Unable to load the MaxMind database (%s): %s", + throw ModuleException(this, InspIRCd::Format("Unable to load the MaxMind database (%s): %s", file.c_str(), MMDB_strerror(result))); // Swap the new database with the old database. diff --git a/src/modules/extra/m_mysql.cpp b/src/modules/extra/m_mysql.cpp index 05637a6a6..23bbdce3d 100644 --- a/src/modules/extra/m_mysql.cpp +++ b/src/modules/extra/m_mysql.cpp @@ -432,7 +432,7 @@ class SQLConnection final void ModuleSQL::init() { if (mysql_library_init(0, NULL, NULL)) - throw ModuleException("Unable to initialise the MySQL library!"); + throw ModuleException(this, "Unable to initialise the MySQL library!"); Dispatcher = new DispatcherThread(this); Dispatcher->Start(); diff --git a/src/modules/extra/m_regex_pcre.cpp b/src/modules/extra/m_regex_pcre.cpp index 368e3618d..681dd4021 100644 --- a/src/modules/extra/m_regex_pcre.cpp +++ b/src/modules/extra/m_regex_pcre.cpp @@ -43,7 +43,7 @@ class PCREPattern final pcre2_code* regex; public: - PCREPattern(const std::string& pattern, uint8_t options) + PCREPattern(const Module* mod, const std::string& pattern, uint8_t options) : Regex::Pattern(pattern, options) { int flags = 0; @@ -57,7 +57,7 @@ class PCREPattern final { PCRE2_UCHAR errorstr[128]; pcre2_get_error_message(errorcode, errorstr, sizeof errorstr); - throw Regex::Exception(pattern, reinterpret_cast<const char*>(errorstr), erroroffset); + throw Regex::Exception(mod, pattern, reinterpret_cast<const char*>(errorstr), erroroffset); } } diff --git a/src/modules/extra/m_regex_posix.cpp b/src/modules/extra/m_regex_posix.cpp index eaa5b37ee..bbde6ab35 100644 --- a/src/modules/extra/m_regex_posix.cpp +++ b/src/modules/extra/m_regex_posix.cpp @@ -35,7 +35,7 @@ class POSIXPattern final regex_t regex; public: - POSIXPattern(const std::string& pattern, uint8_t options) + POSIXPattern(const Module* mod, const std::string& pattern, uint8_t options) : Regex::Pattern(pattern, options) { int flags = REG_EXTENDED | REG_NOSUB; @@ -54,7 +54,7 @@ class POSIXPattern final regerror(error, ®ex, &errormsg[0], errormsg.size()); regfree(®ex); - throw Regex::Exception(pattern, std::string(&errormsg[0], errormsg.size())); + throw Regex::Exception(mod, pattern, std::string(&errormsg[0], errormsg.size())); } ~POSIXPattern() override diff --git a/src/modules/extra/m_regex_re2.cpp b/src/modules/extra/m_regex_re2.cpp index 78ccccd0a..a9f1843bb 100644 --- a/src/modules/extra/m_regex_re2.cpp +++ b/src/modules/extra/m_regex_re2.cpp @@ -46,12 +46,12 @@ class RE2Pattern final } public: - RE2Pattern(const std::string& pattern, uint8_t options) + RE2Pattern(const Module* mod, const std::string& pattern, uint8_t options) : Regex::Pattern(pattern, options) , regex(pattern, BuildOptions(options)) { if (!regex.ok()) - throw Regex::Exception(pattern, regex.error()); + throw Regex::Exception(mod, pattern, regex.error()); } bool IsMatch(const std::string& text) override diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index d5cd626a0..1db07d94a 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -81,8 +81,10 @@ namespace GnuTLS : public ModuleException { public: - Exception(const std::string& reason) - : ModuleException(reason) { } + Exception(const std::string& msg) + : ModuleException(thismod, msg) + { + } }; void ThrowOnError(int errcode, const char* msg) @@ -1108,7 +1110,7 @@ class ModuleSSLGnuTLS final auto tags = ServerInstance->Config->ConfTags("sslprofile"); if (tags.empty()) - throw ModuleException("You have not specified any <sslprofile> tags that are usable by this module!"); + throw ModuleException(this, "You have not specified any <sslprofile> tags that are usable by this module!"); for (const auto& [_, tag] : tags) { @@ -1133,7 +1135,7 @@ class ModuleSSLGnuTLS final } catch (CoreException& ex) { - throw ModuleException("Error while initializing TLS profile \"" + name + "\" at " + tag->source.str() + " - " + ex.GetReason()); + throw ModuleException(this, "Error while initializing TLS profile \"" + name + "\" at " + tag->source.str() + " - " + ex.GetReason()); } newprofiles.push_back(prov); diff --git a/src/modules/extra/m_ssl_mbedtls.cpp b/src/modules/extra/m_ssl_mbedtls.cpp index 8e1c382a9..f58f519db 100644 --- a/src/modules/extra/m_ssl_mbedtls.cpp +++ b/src/modules/extra/m_ssl_mbedtls.cpp @@ -51,14 +51,18 @@ #include <mbedtls/debug.h> #endif +static Module* thismod; + namespace mbedTLS { class Exception final : public ModuleException { public: - Exception(const std::string& reason) - : ModuleException(reason) { } + Exception(const std::string& msg) + : ModuleException(thismod, msg) + { + } }; std::string ErrorToString(int errcode) @@ -880,7 +884,7 @@ class ModuleSSLmbedTLS final auto tags = ServerInstance->Config->ConfTags("sslprofile"); if (tags.empty()) - throw ModuleException("You have not specified any <sslprofile> tags that are usable by this module!"); + throw ModuleException(this, "You have not specified any <sslprofile> tags that are usable by this module!"); for (const auto& [_, tag] : tags) { @@ -905,7 +909,7 @@ class ModuleSSLmbedTLS final } catch (CoreException& ex) { - throw ModuleException("Error while initializing TLS profile \"" + name + "\" at " + tag->source.str() + " - " + ex.GetReason()); + throw ModuleException(this, "Error while initializing TLS profile \"" + name + "\" at " + tag->source.str() + " - " + ex.GetReason()); } newprofiles.push_back(prov); @@ -923,6 +927,7 @@ class ModuleSSLmbedTLS final ModuleSSLmbedTLS() : Module(VF_VENDOR, "Allows TLS encrypted connections using the mbedTLS library.") { + thismod = this; } void init() override @@ -932,7 +937,7 @@ class ModuleSSLmbedTLS final ServerInstance->Logs.Log(MODNAME, LOG_DEFAULT, "mbedTLS lib version %s module was compiled for " MBEDTLS_VERSION_STRING, verbuf); if (!ctr_drbg.Seed(entropy)) - throw ModuleException("CTR DRBG seed failed"); + throw ModuleException(this, "CTR DRBG seed failed"); } void ReadConfig(ConfigStatus& status) override diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 98cb1527f..d4db4d180 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -54,6 +54,7 @@ static bool SelfSigned = false; static int exdataindex; +static Module* thismod; char* get_error() { @@ -69,8 +70,10 @@ namespace OpenSSL : public ModuleException { public: - Exception(const std::string& reason) - : ModuleException(reason) { } + Exception(const std::string& msg) + : ModuleException(thismod, msg) + { + } }; class DHParams final @@ -211,14 +214,14 @@ namespace OpenSSL } else if (!stdalgo::string::equalsci(crlmode, "leaf")) { - throw ModuleException("Unknown mode '" + crlmode + "'; expected either 'chain' (default) or 'leaf'"); + throw ModuleException(thismod, "Unknown mode '" + crlmode + "'; expected either 'chain' (default) or 'leaf'"); } /* Load CRL files */ X509_STORE* store = SSL_CTX_get_cert_store(ctx); if (!store) { - throw ModuleException("Unable to get X509_STORE from TLS context; this should never happen"); + throw ModuleException(thismod, "Unable to get X509_STORE from TLS context; this should never happen"); } ERR_clear_error(); if (!X509_STORE_load_locations(store, @@ -226,13 +229,13 @@ namespace OpenSSL crlpath.empty() ? NULL : crlpath.c_str())) { unsigned long err = ERR_get_error(); - throw ModuleException("Unable to load CRL file '" + crlfile + "' or CRL path '" + crlpath + "': '" + (err ? ERR_error_string(err, NULL) : "unknown") + "'"); + throw ModuleException(thismod, "Unable to load CRL file '" + crlfile + "' or CRL path '" + crlpath + "': '" + (err ? ERR_error_string(err, NULL) : "unknown") + "'"); } /* Set CRL mode */ if (X509_STORE_set_flags(store, crlflags) != 1) { - throw ModuleException("Unable to set X509 CRL flags"); + throw ModuleException(thismod, "Unable to set X509 CRL flags"); } } @@ -930,7 +933,7 @@ class ModuleSSLOpenSSL final ProfileList newprofiles; auto tags = ServerInstance->Config->ConfTags("sslprofile"); if (tags.empty()) - throw ModuleException("You have not specified any <sslprofile> tags that are usable by this module!"); + throw ModuleException(this, "You have not specified any <sslprofile> tags that are usable by this module!"); for (const auto& [_, tag] : tags) { @@ -954,7 +957,7 @@ class ModuleSSLOpenSSL final } catch (CoreException& ex) { - throw ModuleException("Error while initializing TLS profile \"" + name + "\" at " + tag->source.str() + " - " + ex.GetReason()); + throw ModuleException(this, "Error while initializing TLS profile \"" + name + "\" at " + tag->source.str() + " - " + ex.GetReason()); } newprofiles.push_back(prov); @@ -973,6 +976,8 @@ class ModuleSSLOpenSSL final // Initialize OpenSSL OPENSSL_init_ssl(0, NULL); biomethods = OpenSSL::BIOMethod::alloc(); + + thismod = this; } ~ModuleSSLOpenSSL() override @@ -988,7 +993,7 @@ class ModuleSSLOpenSSL final char exdatastr[] = "inspircd"; exdataindex = SSL_get_ex_new_index(0, exdatastr, NULL, NULL, NULL); if (exdataindex < 0) - throw ModuleException("Failed to register application specific data"); + throw ModuleException(this, "Failed to register application specific data"); } void ReadConfig(ConfigStatus& status) override diff --git a/src/modules/m_alias.cpp b/src/modules/m_alias.cpp index 8ce6a5a9f..4dc1aa477 100644 --- a/src/modules/m_alias.cpp +++ b/src/modules/m_alias.cpp @@ -89,11 +89,11 @@ class ModuleAlias final Alias a; a.AliasedCommand = tag->getString("text"); if (a.AliasedCommand.empty()) - throw ModuleException("<alias:text> is empty! at " + tag->source.str()); + throw ModuleException(this, "<alias:text> is empty! at " + tag->source.str()); tag->readString("replace", a.ReplaceFormat, true); if (a.ReplaceFormat.empty()) - throw ModuleException("<alias:replace> is empty! at " + tag->source.str()); + throw ModuleException(this, "<alias:replace> is empty! at " + tag->source.str()); a.RequiredNick = tag->getString("requires"); a.ServiceOnly = tag->getBool("service", tag->getBool("uline")); diff --git a/src/modules/m_bcrypt.cpp b/src/modules/m_bcrypt.cpp index 5768f42a8..c6eebbb96 100644 --- a/src/modules/m_bcrypt.cpp +++ b/src/modules/m_bcrypt.cpp @@ -37,7 +37,7 @@ class BCryptProvider final char salt[32]; if (!_crypt_gensalt_blowfish_rn("$2a$", rounds, entropy, sizeof(entropy), salt, sizeof(salt))) - throw ModuleException("Could not generate salt - this should never happen"); + throw ModuleException(creator, "Could not generate salt - this should never happen"); return salt; } diff --git a/src/modules/m_cap.cpp b/src/modules/m_cap.cpp index 15d2f9ca4..ccb01851f 100644 --- a/src/modules/m_cap.cpp +++ b/src/modules/m_cap.cpp @@ -83,7 +83,7 @@ class Cap::ManagerImpl final if (!(used & bit)) return bit; } - throw ModuleException("Too many caps"); + throw ModuleException(creator, "Too many caps"); } void OnReloadModuleSave(Module* mod, ReloadModule::CustomData& cd) override diff --git a/src/modules/m_chanlog.cpp b/src/modules/m_chanlog.cpp index 84cea2d0d..c0be029b1 100644 --- a/src/modules/m_chanlog.cpp +++ b/src/modules/m_chanlog.cpp @@ -51,7 +51,7 @@ class ModuleChanLog final std::string snomasks = tag->getString("snomasks"); if (channel.empty() || snomasks.empty()) { - throw ModuleException("Malformed chanlog tag at " + tag->source.str()); + throw ModuleException(this, "Malformed chanlog tag at " + tag->source.str()); } for (const auto& snomask : snomasks) diff --git a/src/modules/m_cloaking.cpp b/src/modules/m_cloaking.cpp index f52c3bc54..03d4a9db2 100644 --- a/src/modules/m_cloaking.cpp +++ b/src/modules/m_cloaking.cpp @@ -469,7 +469,7 @@ class ModuleCloaking final { auto tags = ServerInstance->Config->ConfTags("cloak"); if (tags.empty()) - throw ModuleException("You have loaded the cloaking module but not configured any <cloak> tags!"); + throw ModuleException(this, "You have loaded the cloaking module but not configured any <cloak> tags!"); bool firstcloak = true; std::vector<CloakInfo> newcloaks; @@ -478,11 +478,11 @@ class ModuleCloaking final // Ensure that we have the <cloak:key> parameter. const std::string key = tag->getString("key"); if (key.empty()) - throw ModuleException("You have not defined a cloaking key. Define <cloak:key> as a " + ConvToStr(minkeylen) + "+ character network-wide secret, at " + tag->source.str()); + throw ModuleException(this, "You have not defined a cloaking key. Define <cloak:key> as a " + ConvToStr(minkeylen) + "+ character network-wide secret, at " + tag->source.str()); // If we are the first cloak method then mandate a strong key. if (firstcloak && key.length() < minkeylen) - throw ModuleException("Your cloaking key is not secure. It should be at least " + ConvToStr(minkeylen) + " characters long, at " + tag->source.str()); + throw ModuleException(this, "Your cloaking key is not secure. It should be at least " + ConvToStr(minkeylen) + " characters long, at " + tag->source.str()); firstcloak = false; const bool ignorecase = tag->getBool("ignorecase"); @@ -497,7 +497,7 @@ class ModuleCloaking final else if (stdalgo::string::equalsci(mode, "full")) newcloaks.emplace_back(MODE_OPAQUE, key, prefix, suffix, ignorecase); else - throw ModuleException(mode + " is an invalid value for <cloak:mode>; acceptable values are 'half' and 'full', at " + tag->source.str()); + throw ModuleException(this, mode + " is an invalid value for <cloak:mode>; acceptable values are 'half' and 'full', at " + tag->source.str()); } // The cloak configuration was valid so we can apply it. diff --git a/src/modules/m_codepage.cpp b/src/modules/m_codepage.cpp index 5d75e18d7..78b67bcf1 100644 --- a/src/modules/m_codepage.cpp +++ b/src/modules/m_codepage.cpp @@ -262,18 +262,18 @@ class ModuleCodepage final const std::string name = codepagetag->getString("name"); if (name.empty()) - throw ModuleException("<codepage:name> is a required field!"); + throw ModuleException(this, "<codepage:name> is a required field!"); std::unique_ptr<Codepage> newcodepage = std::make_unique<SingleByteCodepage>(); for (const auto& [_, tag] : ServerInstance->Config->ConfTags("cpchars")) { unsigned long begin = tag->getUInt("begin", tag->getUInt("index", 0)); if (!begin) - throw ModuleException("<cpchars> tag without index or begin specified at " + tag->source.str()); + throw ModuleException(this, "<cpchars> tag without index or begin specified at " + tag->source.str()); unsigned long end = tag->getUInt("end", begin); if (begin > end) - throw ModuleException("<cpchars:begin> must be lower than <cpchars:end> at " + tag->source.str()); + throw ModuleException(this, "<cpchars:begin> must be lower than <cpchars:end> at " + tag->source.str()); bool front = tag->getBool("front", false); for (unsigned long pos = begin; pos <= end; ++pos) @@ -287,11 +287,11 @@ class ModuleCodepage final break; case Codepage::ACR_NOT_VALID: - throw ModuleException(InspIRCd::Format("<cpchars> tag contains a forbidden character: %lu at %s", + throw ModuleException(this, InspIRCd::Format("<cpchars> tag contains a forbidden character: %lu at %s", pos, tag->source.str().c_str())); case Codepage::ACR_NOT_VALID_AT_FRONT: - throw ModuleException(InspIRCd::Format("<cpchars> tag contains a forbidden front character: %lu at %s", + throw ModuleException(this, InspIRCd::Format("<cpchars> tag contains a forbidden front character: %lu at %s", pos, tag->source.str().c_str())); } } @@ -301,14 +301,14 @@ class ModuleCodepage final { unsigned long lower = tag->getUInt("lower", 0); if (!lower) - throw ModuleException("<cpcase:lower> is required at " + tag->source.str()); + throw ModuleException(this, "<cpcase:lower> is required at " + tag->source.str()); unsigned long upper = tag->getUInt("upper", 0); if (!upper) - throw ModuleException("<cpcase:upper> is required at " + tag->source.str()); + throw ModuleException(this, "<cpcase:upper> is required at " + tag->source.str()); if (!newcodepage->Map(upper, lower)) - throw ModuleException("Malformed <cpcase> tag at " + tag->source.str()); + throw ModuleException(this, "Malformed <cpcase> tag at " + tag->source.str()); ServerInstance->Logs.Log(MODNAME, LOG_DEBUG, "Marked %lu (%.4s) as the lower case version of %lu (%.4s)", lower, reinterpret_cast<unsigned char*>(&lower), upper, reinterpret_cast<unsigned char*>(&upper)); diff --git a/src/modules/m_customprefix.cpp b/src/modules/m_customprefix.cpp index 52af6e846..b077ef7e9 100644 --- a/src/modules/m_customprefix.cpp +++ b/src/modules/m_customprefix.cpp @@ -61,20 +61,20 @@ class ModuleCustomPrefix final { const std::string name = tag->getString("name"); if (name.empty()) - throw ModuleException("<customprefix:name> must be specified at " + tag->source.str()); + throw ModuleException(this, "<customprefix:name> must be specified at " + tag->source.str()); if (name.find(' ') != std::string::npos) - throw ModuleException("<customprefix:name> must not contain spaces at " + tag->source.str()); + throw ModuleException(this, "<customprefix:name> must not contain spaces at " + tag->source.str()); if (tag->getBool("change")) { ModeHandler* mh = ServerInstance->Modes.FindMode(name, MODETYPE_CHANNEL); if (!mh) - throw ModuleException("<customprefix:change> specified for a nonexistent mode at " + tag->source.str()); + throw ModuleException(this, "<customprefix:change> specified for a nonexistent mode at " + tag->source.str()); PrefixMode* pm = mh->IsPrefixMode(); if (!pm) - throw ModuleException("<customprefix:change> specified for a non-prefix mode at " + tag->source.str()); + throw ModuleException(this, "<customprefix:change> specified for a non-prefix mode at " + tag->source.str()); unsigned int rank = static_cast<unsigned int>(tag->getUInt("rank", pm->GetPrefixRank(), 0, UINT_MAX)); unsigned int setrank = static_cast<unsigned int>(tag->getUInt("ranktoset", pm->GetLevelRequired(true), rank, UINT_MAX)); @@ -89,11 +89,11 @@ class ModuleCustomPrefix final const std::string letter = tag->getString("letter"); if (letter.length() != 1) - throw ModuleException("<customprefix:letter> must be set to a mode character at " + tag->source.str()); + throw ModuleException(this, "<customprefix:letter> must be set to a mode character at " + tag->source.str()); const std::string prefix = tag->getString("prefix"); if (prefix.length() != 1) - throw ModuleException("<customprefix:prefix> must be set to a mode prefix at " + tag->source.str()); + throw ModuleException(this, "<customprefix:prefix> must be set to a mode prefix at " + tag->source.str()); try { @@ -103,7 +103,7 @@ class ModuleCustomPrefix final } catch (ModuleException& e) { - throw ModuleException(e.GetReason() + " (while creating mode from " + tag->source.str() + ")"); + throw ModuleException(this, e.GetReason() + " (while creating mode from " + tag->source.str() + ")"); } } } diff --git a/src/modules/m_customtitle.cpp b/src/modules/m_customtitle.cpp index ef9c0ae1c..9833c70f7 100644 --- a/src/modules/m_customtitle.cpp +++ b/src/modules/m_customtitle.cpp @@ -118,11 +118,11 @@ class ModuleCustomTitle final { std::string name = tag->getString("name", "", 1); if (name.empty()) - throw ModuleException("<title:name> is empty at " + tag->source.str()); + throw ModuleException(this, "<title:name> is empty at " + tag->source.str()); std::string pass = tag->getString("password"); if (pass.empty()) - throw ModuleException("<title:password> is empty at " + tag->source.str()); + throw ModuleException(this, "<title:password> is empty at " + tag->source.str()); const std::string hash = tag->getString("hash", "plaintext", 1); if (stdalgo::string::equalsci(hash, "plaintext")) diff --git a/src/modules/m_denychans.cpp b/src/modules/m_denychans.cpp index 30541920b..a2a64d15b 100644 --- a/src/modules/m_denychans.cpp +++ b/src/modules/m_denychans.cpp @@ -78,7 +78,7 @@ class ModuleDenyChannels final // Ensure that we have the <goodchan:name> parameter. const std::string name = tag->getString("name"); if (name.empty()) - throw ModuleException("<goodchan:name> is a mandatory field, at " + tag->source.str()); + throw ModuleException(this, "<goodchan:name> is a mandatory field, at " + tag->source.str()); goodchans.push_back(name); } @@ -89,19 +89,19 @@ class ModuleDenyChannels final // Ensure that we have the <badchan:name> parameter. const std::string name = tag->getString("name"); if (name.empty()) - throw ModuleException("<badchan:name> is a mandatory field, at " + tag->source.str()); + throw ModuleException(this, "<badchan:name> is a mandatory field, at " + tag->source.str()); // Ensure that we have the <badchan:reason> parameter. const std::string reason = tag->getString("reason"); if (reason.empty()) - throw ModuleException("<badchan:reason> is a mandatory field, at " + tag->source.str()); + throw ModuleException(this, "<badchan:reason> is a mandatory field, at " + tag->source.str()); const std::string redirect = tag->getString("redirect"); if (!redirect.empty()) { // Ensure that <badchan:redirect> contains a channel name. if (!ServerInstance->Channels.IsChannel(redirect)) - throw ModuleException("<badchan:redirect> is not a valid channel name, at " + tag->source.str()); + throw ModuleException(this, "<badchan:redirect> is not a valid channel name, at " + tag->source.str()); // We defer the rest of the validation of the redirect channel until we have // finished parsing all of the badchans. @@ -136,7 +136,7 @@ class ModuleDenyChannels final for (const auto& badchanredir : badchans) { if (InspIRCd::Match(badchan.redirect, badchanredir.name)) - throw ModuleException("<badchan:redirect> cannot be a blacklisted channel name"); + throw ModuleException(this, "<badchan:redirect> cannot be a blacklisted channel name"); } } diff --git a/src/modules/m_disable.cpp b/src/modules/m_disable.cpp index fc9ae90e9..a49e487ff 100644 --- a/src/modules/m_disable.cpp +++ b/src/modules/m_disable.cpp @@ -48,13 +48,13 @@ class ModuleDisable final { // Check that the character is a valid mode letter. if (!ModeParser::IsModeChar(chr)) - throw ModuleException(InspIRCd::Format("Invalid mode '%c' was specified in <disabled:%s> at %s", + throw ModuleException(this, InspIRCd::Format("Invalid mode '%c' was specified in <disabled:%s> at %s", chr, field.c_str(), tag->source.str().c_str())); // Check that the mode actually exists. ModeHandler* mh = ServerInstance->Modes.FindMode(chr, type); if (!mh) - throw ModuleException(InspIRCd::Format("Nonexistent mode '%c' was specified in <disabled:%s> at %s", + throw ModuleException(this, InspIRCd::Format("Nonexistent mode '%c' was specified in <disabled:%s> at %s", chr, field.c_str(), tag->source.str().c_str())); // Disable the mode. @@ -93,7 +93,7 @@ class ModuleDisable final // Check that the command actually exists. Command* handler = ServerInstance->Parser.GetHandler(command); if (!handler) - throw ModuleException(InspIRCd::Format("Nonexistent command '%s' was specified in <disabled:commands> at %s", + throw ModuleException(this, InspIRCd::Format("Nonexistent command '%s' was specified in <disabled:commands> at %s", command.c_str(), tag->source.str().c_str())); // Prevent admins from disabling MODULES for transparency reasons. diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp index 6c9e56a2a..db9c2ed01 100644 --- a/src/modules/m_dnsbl.cpp +++ b/src/modules/m_dnsbl.cpp @@ -103,15 +103,15 @@ public: // If action is set to gline, kline, or zline then the duration for an X-line to last for. unsigned long xlineduration; - DNSBLEntry(std::shared_ptr<ConfigTag> tag) + DNSBLEntry(const Module* mod, std::shared_ptr<ConfigTag> tag) { name = tag->getString("name"); if (name.empty()) - throw ModuleException("<dnsbl:name> can not be empty at " + tag->source.str()); + throw ModuleException(mod, "<dnsbl:name> can not be empty at " + tag->source.str()); domain = tag->getString("domain"); if (domain.empty()) - throw ModuleException("<dnsbl:domain> can not be empty at " + tag->source.str()); + throw ModuleException(mod, "<dnsbl:domain> can not be empty at " + tag->source.str()); action = tag->getEnum("action", Action::KILL, { { "gline", Action::GLINE }, @@ -137,14 +137,14 @@ public: for (long record = 0; (record = recordrange.GetToken()); ) { if (record < 0 || record > UCHAR_MAX) - throw ModuleException("<dnsbl:records> can only hold records between 0 and 255 at " + tag->source.str()); + throw ModuleException(mod, "<dnsbl:records> can only hold records between 0 and 255 at " + tag->source.str()); records.set(record); } } else { - throw ModuleException(typestr + " is an invalid value for <dnsbl:type>; acceptable values are 'bitmask' or 'records' at " + throw ModuleException(mod, typestr + " is an invalid value for <dnsbl:type>; acceptable values are 'bitmask' or 'records' at " + tag->source.str()); } @@ -387,7 +387,7 @@ class ModuleDNSBL final DNSBLEntries newdnsbls; for (const auto& [_, tag] : ServerInstance->Config->ConfTags("dnsbl")) { - auto entry = std::make_shared<DNSBLEntry>(tag); + auto entry = std::make_shared<DNSBLEntry>(this, tag); newdnsbls.push_back(entry); } dnsbls.swap(newdnsbls); diff --git a/src/modules/m_filter.cpp b/src/modules/m_filter.cpp index f32da94ca..09fe913f9 100644 --- a/src/modules/m_filter.cpp +++ b/src/modules/m_filter.cpp @@ -62,6 +62,8 @@ enum FilterAction FA_NONE }; +static Module* thismod; + class FilterResult final { public: @@ -88,7 +90,7 @@ class FilterResult final , from_config(cfg) { if (!RegexEngine) - throw ModuleException("Regex module implementing '"+RegexEngine.GetProvider()+"' is not loaded!"); + throw ModuleException(thismod, "Regex module implementing '"+RegexEngine.GetProvider()+"' is not loaded!"); regex = RegexEngine->Create(free); this->FillFlags(fla); } @@ -359,6 +361,7 @@ ModuleFilter::ModuleFilter() , filtcommand(this) , RegexEngine(this) { + thismod = this; } void ModuleFilter::init() @@ -701,13 +704,13 @@ FilterResult ModuleFilter::DecodeFilter(const std::string &data) tokens.GetMiddle(res.freeform); tokens.GetMiddle(filteraction); if (!StringToFilterAction(filteraction, res.action)) - throw ModuleException("Invalid action: " + filteraction); + throw ModuleException(this, "Invalid action: " + filteraction); std::string filterflags; tokens.GetMiddle(filterflags); char c = res.FillFlags(filterflags); if (c != 0) - throw ModuleException("Invalid flag: '" + std::string(1, c) + "'"); + throw ModuleException(this, "Invalid flag: '" + std::string(1, c) + "'"); std::string duration; tokens.GetMiddle(duration); diff --git a/src/modules/m_gateway.cpp b/src/modules/m_gateway.cpp index 4cc1e0eae..b408afd24 100644 --- a/src/modules/m_gateway.cpp +++ b/src/modules/m_gateway.cpp @@ -368,7 +368,7 @@ class ModuleGateway final // Ensure that we have the <gateway:mask> parameter. if (masks.empty()) - throw ModuleException("<" + tag->name + ":mask> is a mandatory field, at " + tag->source.str()); + throw ModuleException(this, "<" + tag->name + ":mask> is a mandatory field, at " + tag->source.str()); // Determine what lookup type this host uses. const std::string type = tag->getString("type"); @@ -388,7 +388,7 @@ class ModuleGateway final // WebIRC blocks require a password. if (fingerprint.empty() && password.empty()) - throw ModuleException("When using <" + tag->name + " type=\"webirc\"> either the fingerprint or password field is required, at " + tag->source.str()); + throw ModuleException(this, "When using <" + tag->name + " type=\"webirc\"> either the fingerprint or password field is required, at " + tag->source.str()); if (!password.empty() && stdalgo::string::equalsci(passwordhash, "plaintext")) { @@ -400,7 +400,7 @@ class ModuleGateway final } else { - throw ModuleException(type + " is an invalid <" + tag->name + ":mask> type, at " + tag->source.str()); + throw ModuleException(this, type + " is an invalid <" + tag->name + ":mask> type, at " + tag->source.str()); } } diff --git a/src/modules/m_helpop.cpp b/src/modules/m_helpop.cpp index 4ad952479..0984ac91c 100644 --- a/src/modules/m_helpop.cpp +++ b/src/modules/m_helpop.cpp @@ -115,23 +115,23 @@ class ModuleHelpop final HelpMap newhelp; auto tags = ServerInstance->Config->ConfTags("helpop"); if (tags.empty()) - throw ModuleException("You have loaded the helpop module but not configured any help topics!"); + throw ModuleException(this, "You have loaded the helpop module but not configured any help topics!"); for (const auto& [_, tag] : tags) { // Attempt to read the help key. const std::string key = tag->getString("key"); if (key.empty()) - throw ModuleException(InspIRCd::Format("<helpop:key> is empty at %s", tag->source.str().c_str())); + throw ModuleException(this, InspIRCd::Format("<helpop:key> is empty at %s", tag->source.str().c_str())); else if (irc::equals(key, "index")) - throw ModuleException(InspIRCd::Format("<helpop:key> is set to \"index\" which is reserved at %s", tag->source.str().c_str())); + throw ModuleException(this, InspIRCd::Format("<helpop:key> is set to \"index\" which is reserved at %s", tag->source.str().c_str())); else if (key.length() > longestkey) longestkey = key.length(); // Attempt to read the help value. std::string value; if (!tag->readString("value", value, true) || value.empty()) - throw ModuleException(InspIRCd::Format("<helpop:value> is empty at %s", tag->source.str().c_str())); + throw ModuleException(this, InspIRCd::Format("<helpop:value> is empty at %s", tag->source.str().c_str())); // Parse the help body. Empty lines are replaced with a single // space because some clients are unable to show blank lines. @@ -144,7 +144,7 @@ class ModuleHelpop final const std::string title = tag->getString("title", InspIRCd::Format("*** Help for %s", key.c_str()), 1); if (!newhelp.emplace(key, HelpTopic(helpmsg, title)).second) { - throw ModuleException(InspIRCd::Format("<helpop> tag with duplicate key '%s' at %s", + throw ModuleException(this, InspIRCd::Format("<helpop> tag with duplicate key '%s' at %s", key.c_str(), tag->source.str().c_str())); } } diff --git a/src/modules/m_hidelist.cpp b/src/modules/m_hidelist.cpp index e52f9de32..7dde09e97 100644 --- a/src/modules/m_hidelist.cpp +++ b/src/modules/m_hidelist.cpp @@ -67,7 +67,7 @@ class ModuleHideList final { std::string modename = tag->getString("mode"); if (modename.empty()) - throw ModuleException("Empty <hidelist:mode> at " + tag->source.str()); + throw ModuleException(this, "Empty <hidelist:mode> at " + tag->source.str()); // If rank is set to 0 everyone inside the channel can view the list, // but non-members may not unsigned long rank = tag->getUInt("rank", HALFOP_VALUE); diff --git a/src/modules/m_hidemode.cpp b/src/modules/m_hidemode.cpp index f5d7c0c6a..b303b1841 100644 --- a/src/modules/m_hidemode.cpp +++ b/src/modules/m_hidemode.cpp @@ -38,7 +38,7 @@ class Settings final return 0; } - void Load() + void Load(const Module* mod) { RanksToSeeMap newranks; @@ -46,11 +46,11 @@ class Settings final { const std::string modename = tag->getString("mode"); if (modename.empty()) - throw ModuleException("<hidemode:mode> is empty at " + tag->source.str()); + throw ModuleException(mod, "<hidemode:mode> is empty at " + tag->source.str()); unsigned long rank = tag->getUInt("rank", 0); if (!rank) - throw ModuleException("<hidemode:rank> must be greater than 0 at " + tag->source.str()); + throw ModuleException(mod, "<hidemode:rank> must be greater than 0 at " + tag->source.str()); ServerInstance->Logs.Log(MODNAME, LOG_DEBUG, "Hiding the %s mode from users below rank %lu", modename.c_str(), rank); newranks.emplace(modename, rank); @@ -197,7 +197,7 @@ class ModuleHideMode final void ReadConfig(ConfigStatus& status) override { - modehook.settings.Load(); + modehook.settings.Load(this); } }; diff --git a/src/modules/m_hostchange.cpp b/src/modules/m_hostchange.cpp index d1f3426b2..5016ed5c4 100644 --- a/src/modules/m_hostchange.cpp +++ b/src/modules/m_hostchange.cpp @@ -156,7 +156,7 @@ private: // Ensure that we have the <hostchange:mask> parameter. const std::string mask = tag->getString("mask"); if (mask.empty()) - throw ModuleException("<hostchange:mask> is a mandatory field, at " + tag->source.str()); + throw ModuleException(this, "<hostchange:mask> is a mandatory field, at " + tag->source.str()); // Determine what type of host rule this is. const std::string action = tag->getString("action"); @@ -175,7 +175,7 @@ private: // Ensure that we have the <hostchange:value> parameter. const std::string value = tag->getString("value"); if (value.empty()) - throw ModuleException("<hostchange:value> is a mandatory field when using the 'set' action, at " + tag->source.str()); + throw ModuleException(this, "<hostchange:value> is a mandatory field when using the 'set' action, at " + tag->source.str()); // The hostname is in the format <value>. rules.emplace_back(tag, mask, value); @@ -183,7 +183,7 @@ private: } else { - throw ModuleException(action + " is an invalid <hostchange:action> type, at " + tag->source.str()); + throw ModuleException(this, action + " is an invalid <hostchange:action> type, at " + tag->source.str()); } } diff --git a/src/modules/m_httpd_acl.cpp b/src/modules/m_httpd_acl.cpp index afdbf2c08..7510725fe 100644 --- a/src/modules/m_httpd_acl.cpp +++ b/src/modules/m_httpd_acl.cpp @@ -88,7 +88,7 @@ class ModuleHTTPAccessList final } else { - throw ModuleException("Invalid HTTP ACL type '" + type + "'"); + throw ModuleException(this, "Invalid HTTP ACL type '" + type + "'"); } } diff --git a/src/modules/m_ident.cpp b/src/modules/m_ident.cpp index b40546fec..caaa8f116 100644 --- a/src/modules/m_ident.cpp +++ b/src/modules/m_ident.cpp @@ -109,13 +109,14 @@ class IdentRequestSocket final time_t age; bool done; /* True if lookup is finished */ - IdentRequestSocket(LocalUser* u) : user(u) + IdentRequestSocket(const Module* mod, LocalUser* luser) + : user(luser) { age = ServerInstance->Time(); SetFd(socket(user->server_sa.family(), SOCK_STREAM, 0)); if (!HasFd()) - throw ModuleException("Could not create socket"); + throw ModuleException(mod, "Could not create socket"); done = false; @@ -140,7 +141,7 @@ class IdentRequestSocket final if (SocketEngine::Bind(GetFd(), bindaddr) < 0) { this->Close(); - throw ModuleException("failed to bind()"); + throw ModuleException(mod, "failed to bind()"); } SocketEngine::NonBlocking(GetFd()); @@ -149,14 +150,14 @@ class IdentRequestSocket final if (SocketEngine::Connect(this, connaddr) == -1 && errno != EINPROGRESS) { this->Close(); - throw ModuleException("connect() failed"); + throw ModuleException(mod, "connect() failed"); } /* Add fd to socket engine */ if (!SocketEngine::AddFd(this, FD_WANT_NO_READ | FD_WANT_POLL_WRITE)) { this->Close(); - throw ModuleException("out of fds"); + throw ModuleException(mod, "out of fds"); } } @@ -343,7 +344,7 @@ class ModuleIdent final try { - isock = new IdentRequestSocket(user); + isock = new IdentRequestSocket(this, user); socket.Set(user, isock); } catch (ModuleException &e) diff --git a/src/modules/m_ircv3_sts.cpp b/src/modules/m_ircv3_sts.cpp index b59025130..3b9794a96 100644 --- a/src/modules/m_ircv3_sts.cpp +++ b/src/modules/m_ircv3_sts.cpp @@ -163,15 +163,15 @@ class ModuleIRCv3STS final // TODO: Multiple SNI profiles auto tag = ServerInstance->Config->ConfValue("sts"); if (tag == ServerInstance->Config->EmptyTag) - throw ModuleException("You must define a STS policy!"); + throw ModuleException(this, "You must define a STS policy!"); const std::string host = tag->getString("host"); if (host.empty()) - throw ModuleException("<sts:host> must contain a hostname, at " + tag->source.str()); + throw ModuleException(this, "<sts:host> must contain a hostname, at " + tag->source.str()); unsigned int port = static_cast<unsigned int>(tag->getUInt("port", 0, 0, UINT16_MAX)); if (!HasValidSSLPort(port)) - throw ModuleException("<sts:port> must be a TLS port, at " + tag->source.str()); + throw ModuleException(this, "<sts:port> must be a TLS port, at " + tag->source.str()); unsigned long duration = tag->getDuration("duration", 5*60, 60); bool preload = tag->getBool("preload"); diff --git a/src/modules/m_nationalchars.cpp b/src/modules/m_nationalchars.cpp index c673078c7..54f1dc962 100644 --- a/src/modules/m_nationalchars.cpp +++ b/src/modules/m_nationalchars.cpp @@ -275,7 +275,7 @@ class ModuleNationalChars final charset = tag->getString("file"); std::string casemapping = tag->getString("casemapping", FileSystem::GetFileName(charset), 1); if (casemapping.find(' ') != std::string::npos) - throw ModuleException("<nationalchars:casemapping> must not contain any spaces!"); + throw ModuleException(this, "<nationalchars:casemapping> must not contain any spaces!"); ServerInstance->Config->CaseMapping = std::move(casemapping); #if defined _WIN32 if (!FileSystem::StartsWithWindowsDriveLetter(charset)) @@ -286,7 +286,7 @@ class ModuleNationalChars final #endif unsigned char* tables[8] = { m_additional, m_additionalMB, m_additionalUp, m_lower, m_upper, m_additionalUtf8, m_additionalUtf8range, m_additionalUtf8interval }; if (!loadtables(charset, tables, 8, 5)) - throw ModuleException("The locale file failed to load. Check your log file for more information."); + throw ModuleException(this, "The locale file failed to load. Check your log file for more information."); forcequit = tag->getBool("forcequit"); CheckForceQuit("National character set changed"); CheckRehash(); diff --git a/src/modules/m_regex_glob.cpp b/src/modules/m_regex_glob.cpp index a0b25e193..569a40731 100644 --- a/src/modules/m_regex_glob.cpp +++ b/src/modules/m_regex_glob.cpp @@ -30,7 +30,7 @@ class GlobPattern final : public Regex::Pattern { public: - GlobPattern(const std::string& pattern, uint8_t options) + GlobPattern(const Module* mod, const std::string& pattern, uint8_t options) : Regex::Pattern(pattern, options) { } diff --git a/src/modules/m_regex_stdlib.cpp b/src/modules/m_regex_stdlib.cpp index 580934400..714ed05aa 100644 --- a/src/modules/m_regex_stdlib.cpp +++ b/src/modules/m_regex_stdlib.cpp @@ -32,7 +32,7 @@ class StdLibPattern final std::regex regex; public: - StdLibPattern(const std::string& pattern, uint8_t options, std::regex::flag_type type) + StdLibPattern(const Module* mod, const std::string& pattern, uint8_t options, std::regex::flag_type type) : Regex::Pattern(pattern, options) { // Convert the generic pattern options to stdlib pattern flags. @@ -46,7 +46,7 @@ class StdLibPattern final } catch(const std::regex_error& error) { - throw Regex::Exception(pattern, error.what()); + throw Regex::Exception(mod, pattern, error.what()); } } @@ -69,7 +69,7 @@ class StdLibEngine final Regex::PatternPtr Create(const std::string& pattern, uint8_t options) const override { - return std::make_shared<StdLibPattern>(pattern, options, regextype); + return std::make_shared<StdLibPattern>(creator, pattern, options, regextype); } }; diff --git a/src/modules/m_restrictchans.cpp b/src/modules/m_restrictchans.cpp index ed47dc31b..12c0de77c 100644 --- a/src/modules/m_restrictchans.cpp +++ b/src/modules/m_restrictchans.cpp @@ -66,7 +66,7 @@ class ModuleRestrictChans final { const std::string name = tag->getString("name"); if (name.empty()) - throw ModuleException("Empty <allowchannel:name> at " + tag->source.str()); + throw ModuleException(this, "Empty <allowchannel:name> at " + tag->source.str()); newallows.insert(name); } diff --git a/src/modules/m_rline.cpp b/src/modules/m_rline.cpp index e52224738..bc599147a 100644 --- a/src/modules/m_rline.cpp +++ b/src/modules/m_rline.cpp @@ -97,9 +97,15 @@ class RLine final class RLineFactory final : public XLineFactory { - public: + private: + const Module* creator; Regex::EngineReference& rxfactory; - RLineFactory(Regex::EngineReference& rx) : XLineFactory("R"), rxfactory(rx) + + public: + RLineFactory(const Module* mod, Regex::EngineReference& rx) + : XLineFactory("R") + , creator(mod) + , rxfactory(rx) { } @@ -110,7 +116,7 @@ class RLineFactory final if (!rxfactory) { ServerInstance->SNO.WriteToSnoMask('a', "Cannot create regexes until engine is set to a loaded provider!"); - throw ModuleException("Regex engine not set or loaded!"); + throw ModuleException(creator, "Regex engine not set or loaded!"); } return new RLine(set_time, duration, source, reason, xline_specific_mask, rxfactory); @@ -213,7 +219,7 @@ class ModuleRLine final : Module(VF_VENDOR | VF_COMMON, "Adds the /RLINE command which allows server operators to prevent users matching a nickname!username@hostname+realname regular expression from connecting to the server.") , Stats::EventListener(this) , rxfactory(this) - , f(rxfactory) + , f(this, rxfactory) , r(this, f) { } diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp index 7aefb000c..eed0e73c0 100644 --- a/src/modules/m_sasl.cpp +++ b/src/modules/m_sasl.cpp @@ -430,7 +430,7 @@ class ModuleSASL final const std::string target = tag->getString("target"); if (target.empty()) - throw ModuleException("<sasl:target> must be set to the name of your services server!"); + throw ModuleException(this, "<sasl:target> must be set to the name of your services server!"); cap.requiressl = tag->getBool("requiressl"); sasl_target = target; diff --git a/src/modules/m_securelist.cpp b/src/modules/m_securelist.cpp index a475c9255..59b704362 100644 --- a/src/modules/m_securelist.cpp +++ b/src/modules/m_securelist.cpp @@ -57,7 +57,7 @@ class ModuleSecureList final { const std::string host = tag->getString("exception"); if (host.empty()) - throw ModuleException("<securehost:exception> is a required field at " + tag->source.str()); + throw ModuleException(this, "<securehost:exception> is a required field at " + tag->source.str()); newallows.push_back(host); } diff --git a/src/modules/m_showfile.cpp b/src/modules/m_showfile.cpp index 3de8df9d3..cb952e127 100644 --- a/src/modules/m_showfile.cpp +++ b/src/modules/m_showfile.cpp @@ -108,13 +108,13 @@ class ModuleShowFile final { std::string cmdname = tag->getString("name"); if (cmdname.empty()) - throw ModuleException("Empty value for 'name'"); + throw ModuleException(this, "Empty value for 'name'"); std::transform(cmdname.begin(), cmdname.end(), cmdname.begin(), ::toupper); const std::string file = tag->getString("file", cmdname); if (file.empty()) - throw ModuleException("Empty value for 'file'"); + throw ModuleException(this, "Empty value for 'file'"); FileReader reader(file); CommandShowFile* sfcmd; @@ -123,12 +123,12 @@ class ModuleShowFile final { // Command exists, check if it is ours if (handler->creator != this) - throw ModuleException("Command " + cmdname + " already exists"); + throw ModuleException(this, "Command " + cmdname + " already exists"); // This is our command, make sure we don't have the same entry twice sfcmd = static_cast<CommandShowFile*>(handler); if (stdalgo::isin(newcmds, sfcmd)) - throw ModuleException("Command " + cmdname + " is already used in a <showfile> tag"); + throw ModuleException(this, "Command " + cmdname + " is already used in a <showfile> tag"); } else { diff --git a/src/modules/m_spanningtree/servercommand.h b/src/modules/m_spanningtree/servercommand.h index 379dbbc19..d530ad666 100644 --- a/src/modules/m_spanningtree/servercommand.h +++ b/src/modules/m_spanningtree/servercommand.h @@ -28,7 +28,7 @@ class ProtocolException final { public: ProtocolException(const std::string& msg) - : ModuleException("Protocol violation: " + msg) + : ModuleException((Module*)Utils->Creator, "Protocol violation: " + msg) { } }; diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp index ce822b607..aad601251 100644 --- a/src/modules/m_spanningtree/utils.cpp +++ b/src/modules/m_spanningtree/utils.cpp @@ -270,25 +270,25 @@ void SpanningTreeUtilities::ReadConfiguration() L->Hidden = tag->getBool("hidden"); if (L->Name.empty()) - throw ModuleException("Invalid configuration, found a link tag without a name!" + (!L->IPAddr.empty() ? " IP address: "+L->IPAddr : "")); + throw ModuleException((Module*)Creator, "Invalid configuration, found a link tag without a name!" + (!L->IPAddr.empty() ? " IP address: "+L->IPAddr : "")); if (L->Name.find('.') == std::string::npos) - throw ModuleException("The link name '"+L->Name+"' is invalid as it must contain at least one '.' character"); + throw ModuleException((Module*)Creator, "The link name '"+L->Name+"' is invalid as it must contain at least one '.' character"); if (L->Name.length() > ServerInstance->Config->Limits.MaxHost) - throw ModuleException("The link name '"+L->Name+"' is invalid as it is longer than " + ConvToStr(ServerInstance->Config->Limits.MaxHost) + " characters"); + throw ModuleException((Module*)Creator, "The link name '"+L->Name+"' is invalid as it is longer than " + ConvToStr(ServerInstance->Config->Limits.MaxHost) + " characters"); if (L->RecvPass.empty()) - throw ModuleException("Invalid configuration for server '"+L->Name+"', recvpass not defined"); + throw ModuleException((Module*)Creator, "Invalid configuration for server '"+L->Name+"', recvpass not defined"); if (L->SendPass.empty()) - throw ModuleException("Invalid configuration for server '"+L->Name+"', sendpass not defined"); + throw ModuleException((Module*)Creator, "Invalid configuration for server '"+L->Name+"', sendpass not defined"); if ((L->SendPass.find(' ') != std::string::npos) || (L->RecvPass.find(' ') != std::string::npos)) - throw ModuleException("Link block '" + L->Name + "' has a password set that contains a space character which is invalid"); + throw ModuleException((Module*)Creator, "Link block '" + L->Name + "' has a password set that contains a space character which is invalid"); if ((L->SendPass[0] == ':') || (L->RecvPass[0] == ':')) - throw ModuleException("Link block '" + L->Name + "' has a password set that begins with a colon (:) which is invalid"); + throw ModuleException((Module*)Creator, "Link block '" + L->Name + "' has a password set that begins with a colon (:) which is invalid"); if (L->IPAddr.empty()) { @@ -318,7 +318,7 @@ void SpanningTreeUtilities::ReadConfiguration() if (A->servers.empty()) { - throw ModuleException("Invalid configuration for autoconnect, server cannot be empty!"); + throw ModuleException((Module*)Creator, "Invalid configuration for autoconnect, server cannot be empty!"); } AutoconnectBlocks.push_back(A); diff --git a/src/modules/m_vhost.cpp b/src/modules/m_vhost.cpp index f4d813ce7..5539ebb86 100644 --- a/src/modules/m_vhost.cpp +++ b/src/modules/m_vhost.cpp @@ -98,15 +98,15 @@ class ModuleVHost final { std::string mask = tag->getString("host"); if (mask.empty()) - throw ModuleException("<vhost:host> is empty! at " + tag->source.str()); + throw ModuleException(this, "<vhost:host> is empty! at " + tag->source.str()); std::string username = tag->getString("user"); if (username.empty()) - throw ModuleException("<vhost:user> is empty! at " + tag->source.str()); + throw ModuleException(this, "<vhost:user> is empty! at " + tag->source.str()); std::string pass = tag->getString("pass"); if (pass.empty()) - throw ModuleException("<vhost:pass> is empty! at " + tag->source.str()); + throw ModuleException(this, "<vhost:pass> is empty! at " + tag->source.str()); const std::string hash = tag->getString("hash", "plaintext", 1); if (stdalgo::string::equalsci(hash, "plaintext")) diff --git a/src/modules/m_websocket.cpp b/src/modules/m_websocket.cpp index 0df7e0818..139abd59d 100644 --- a/src/modules/m_websocket.cpp +++ b/src/modules/m_websocket.cpp @@ -594,7 +594,7 @@ class ModuleWebSocket final { auto tags = ServerInstance->Config->ConfTags("wsorigin"); if (tags.empty()) - throw ModuleException("You have loaded the websocket module but not configured any allowed origins!"); + throw ModuleException(this, "You have loaded the websocket module but not configured any allowed origins!"); WebSocketConfig config; for (const auto& [_, tag] : tags) @@ -602,7 +602,7 @@ class ModuleWebSocket final // Ensure that we have the <wsorigin:allow> parameter. const std::string allow = tag->getString("allow"); if (allow.empty()) - throw ModuleException("<wsorigin:allow> is a mandatory field, at " + tag->source.str()); + throw ModuleException(this, "<wsorigin:allow> is a mandatory field, at " + tag->source.str()); config.allowedorigins.push_back(allow); } @@ -617,7 +617,7 @@ class ModuleWebSocket final else if (stdalgo::string::equalsci(defaultmodestr, "text")) config.defaultmode = WebSocketConfig::DM_TEXT; else - throw ModuleException(defaultmodestr + " is an invalid value for <websocket:defaultmode>; acceptable values are 'binary', 'text' and 'reject', at " + tag->source.str()); + throw ModuleException(this, defaultmodestr + " is an invalid value for <websocket:defaultmode>; acceptable values are 'binary', 'text' and 'reject', at " + tag->source.str()); irc::spacesepstream proxyranges(tag->getString("proxyranges")); for (std::string proxyrange; proxyranges.GetToken(proxyrange); ) |
