diff options
author | Peter Powell <petpow@saberuk.com> | 2017-08-26 17:25:20 +0100 |
---|---|---|
committer | Peter Powell <petpow@saberuk.com> | 2017-08-26 19:01:27 +0100 |
commit | 45fc75457b56bb14ad0f7b99909b96404df69c8c (patch) | |
tree | 6cfff6d7fe565bd8b58346d9f68f982017f9b41b | |
parent | 1f2a8e4db6a4c722de4e090fcd7f710d874de1ed (diff) |
Use DLLManager::RetrieveLastError() on all platforms.
This prevents a bug where we send malformed messages to the client
when dlerror() returns an error message containing more than one
line. This has been observed on macOS but probably will happen on
other UNIX systems too.
This also fixes a potential problem where dlerror() returns NULL
and converting it to std::string causes a crash. I can't see any
way that this might happen but it is better to be safe than sorry.
-rw-r--r-- | include/dynamic.h | 2 | ||||
-rw-r--r-- | src/dynamic.cpp | 15 |
2 files changed, 5 insertions, 12 deletions
diff --git a/include/dynamic.h b/include/dynamic.h index 5e66ddbb0..bbe89dc7e 100644 --- a/include/dynamic.h +++ b/include/dynamic.h @@ -33,11 +33,9 @@ class CoreExport DLLManager : public classbase */ std::string err; -#ifdef _WIN32 /** Sets the last error string */ void RetrieveLastError(); -#endif public: /** This constructor loads the module using dlopen() diff --git a/src/dynamic.cpp b/src/dynamic.cpp index 3a6a151cb..25178cfa1 100644 --- a/src/dynamic.cpp +++ b/src/dynamic.cpp @@ -43,11 +43,7 @@ DLLManager::DLLManager(const char *fname) h = dlopen(fname, RTLD_NOW|RTLD_LOCAL); if (!h) { -#ifdef _WIN32 RetrieveLastError(); -#else - err = dlerror(); -#endif } } @@ -72,11 +68,7 @@ Module* DLLManager::CallInit() initfn.vptr = dlsym(h, MODULE_INIT_STR); if (!initfn.vptr) { -#ifdef _WIN32 RetrieveLastError(); -#else - err = dlerror(); -#endif return NULL; } @@ -94,18 +86,21 @@ std::string DLLManager::GetVersion() return "Unversioned module"; } -#ifdef _WIN32 void DLLManager::RetrieveLastError() { +#if defined _WIN32 char errmsg[500]; DWORD dwErrorCode = GetLastError(); if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)errmsg, _countof(errmsg), NULL) == 0) sprintf_s(errmsg, _countof(errmsg), "Error code: %u", dwErrorCode); SetLastError(ERROR_SUCCESS); err = errmsg; +#else + char* errmsg = dlerror(); + err = errmsg ? errmsg : "Unknown error"; +#endif std::string::size_type p; while ((p = err.find_last_of("\r\n")) != std::string::npos) err.erase(p, 1); } -#endif |