diff options
| author | 2013-05-23 13:19:12 -0400 | |
|---|---|---|
| committer | 2013-05-23 13:19:12 -0400 | |
| commit | da69771af628c6d16b5840f3d642ef70fcbe2170 (patch) | |
| tree | c9a7849e6f20577a32b0e7143d099316a13692c6 /src/helperfuncs.cpp | |
| parent | Change CacheRefreshTimer tick time back to 5 minutes (diff) | |
| download | inspircd++-da69771af628c6d16b5840f3d642ef70fcbe2170.tar.gz inspircd++-da69771af628c6d16b5840f3d642ef70fcbe2170.tar.bz2 inspircd++-da69771af628c6d16b5840f3d642ef70fcbe2170.zip | |
Some systems with whacky va_list implementations do undefined stuff when vsnprintf is called multiple times with the same list, so have InspIRCd::Format va_copy the list before each call
Diffstat (limited to 'src/helperfuncs.cpp')
| -rw-r--r-- | src/helperfuncs.cpp | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp index cc760c535..e86c0bc70 100644 --- a/src/helperfuncs.cpp +++ b/src/helperfuncs.cpp @@ -401,10 +401,22 @@ unsigned long InspIRCd::Duration(const std::string &str) const char* InspIRCd::Format(va_list &vaList, const char* formatString) { static std::vector<char> formatBuffer(1024); - int vsnret = 0; - while ((vsnret = vsnprintf(&formatBuffer[0], formatBuffer.size(), formatString, vaList)) < 0 || static_cast<unsigned int>(vsnret) >= formatBuffer.size()) + + while (true) + { + va_list dst; + va_copy(dst, vaList); + + int vsnret = vsnprintf(&formatBuffer[0], formatBuffer.size(), formatString, dst); + if (vsnret > 0 && static_cast<unsigned>(vsnret) < formatBuffer.size()) + { + return &formatBuffer[0]; + } + formatBuffer.resize(formatBuffer.size() * 2); - return &formatBuffer[0]; + } + + throw CoreException(); } const char* InspIRCd::Format(const char* formatString, ...) |
