diff options
| author | mitchell <unknown> | 2020-01-03 19:36:29 -0500 |
|---|---|---|
| committer | mitchell <unknown> | 2020-01-03 19:36:29 -0500 |
| commit | d04419780a4096dd7d6ddc7c3959356fdc6e64a5 (patch) | |
| tree | c90afd20b17137e9f0def09817fd25c7650dbbb4 | |
| parent | 8accea79edacc04b1dafb84026ce0ce5ecd46af9 (diff) | |
| download | scintilla-mirror-d04419780a4096dd7d6ddc7c3959356fdc6e64a5.tar.gz | |
Backport: Use safe mechanism to convert to function pointers.
Mark noexcept where reasonable. Check that functions are available.
Backport of changeset 7862:f4cf92e43f48.
| -rw-r--r-- | src/ExternalLexer.cxx | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/src/ExternalLexer.cxx b/src/ExternalLexer.cxx index b35e8962a..81e01b179 100644 --- a/src/ExternalLexer.cxx +++ b/src/ExternalLexer.cxx @@ -38,6 +38,16 @@ typedef int (EXT_LEXER_DECL *GetLexerCountFn)(); typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength); typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned int Index); +/// Generic function to convert from a void* to a function pointer. +/// This avoids undefined and conditionally defined behaviour. +template<typename T> +T FunctionPointer(void *function) noexcept { + static_assert(sizeof(T) == sizeof(function), "size mismatch"); + T fp; + memcpy(&fp, &function, sizeof(T)); + return fp; +} + /// Sub-class of LexerModule to use an external lexer. class ExternalLexerModule : public LexerModule { protected: @@ -50,7 +60,7 @@ public: fneFactory(nullptr), name(languageName_){ languageName = name.c_str(); } - virtual void SetExternal(GetLexerFactoryFunction fFactory, int index); + void SetExternal(GetLexerFactoryFunction fFactory, int index) noexcept; }; /// LexerLibrary exists for every External Lexer DLL, contains ExternalLexerModules. @@ -70,10 +80,10 @@ public: ~LexerManager(); static LexerManager *GetInstance(); - static void DeleteInstance(); + static void DeleteInstance() noexcept; void Load(const char *path); - void Clear(); + void Clear() noexcept; private: LexerManager(); @@ -94,7 +104,7 @@ std::unique_ptr<LexerManager> LexerManager::theInstance; // //------------------------------------------ -void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) { +void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) noexcept { fneFactory = fFactory; fnFactory = fFactory(index); } @@ -110,13 +120,16 @@ LexerLibrary::LexerLibrary(const char *moduleName_) { lib.reset(DynamicLibrary::Load(moduleName_)); if (lib->IsValid()) { moduleName = moduleName_; - //Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects - GetLexerCountFn GetLexerCount = (GetLexerCountFn)(sptr_t)lib->FindFunction("GetLexerCount"); + GetLexerCountFn GetLexerCount = FunctionPointer<GetLexerCountFn>(lib->FindFunction("GetLexerCount")); if (GetLexerCount) { // Find functions in the DLL - GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName"); - GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory"); + GetLexerNameFn GetLexerName = FunctionPointer<GetLexerNameFn>(lib->FindFunction("GetLexerName")); + GetLexerFactoryFunction fnFactory = FunctionPointer<GetLexerFactoryFunction>(lib->FindFunction("GetLexerFactory")); + + if (!GetLexerName || !fnFactory) { + return; + } const int nl = GetLexerCount(); @@ -157,7 +170,7 @@ LexerManager *LexerManager::GetInstance() { } /// Delete any LexerManager instance... -void LexerManager::DeleteInstance() { +void LexerManager::DeleteInstance() noexcept { theInstance.reset(); } @@ -178,7 +191,7 @@ void LexerManager::Load(const char *path) { libraries.push_back(std::unique_ptr<LexerLibrary>(lib)); } -void LexerManager::Clear() { +void LexerManager::Clear() noexcept { libraries.clear(); } |
