summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Powell <petpow@saberuk.com>2017-08-26 17:25:20 +0100
committerPeter Powell <petpow@saberuk.com>2017-08-26 19:01:27 +0100
commit45fc75457b56bb14ad0f7b99909b96404df69c8c (patch)
tree6cfff6d7fe565bd8b58346d9f68f982017f9b41b
parent1f2a8e4db6a4c722de4e090fcd7f710d874de1ed (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.h2
-rw-r--r--src/dynamic.cpp15
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