fixed: XArchEval "what" returns garbage (memory deleted).

This commit is contained in:
Nick Bolton 2014-03-20 10:32:40 +00:00
parent 8283955765
commit 44a98c6c9d
8 changed files with 53 additions and 90 deletions

View File

@ -1,38 +0,0 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2012 Bolton Software Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "arch/XArch.h"
//
// XArch
//
const char*
XArch::what() const _NOEXCEPT
{
const char* what = std::runtime_error::what();
try {
if (strlen(what) == 0 && m_eval != NULL) {
return m_eval->eval().c_str();
}
}
catch (...) {
// ignore
}
return what;
}

View File

@ -55,26 +55,15 @@ string for that error code.
*/ */
class XArchEval { class XArchEval {
public: public:
XArchEval() { } virtual std::string eval() const = 0;
virtual ~XArchEval() { }
virtual XArchEval* clone() const throw() = 0;
virtual std::string eval() const throw() = 0;
}; };
//! Generic exception architecture dependent library //! Generic exception architecture dependent library
class XArch : public std::runtime_error { class XArch : public std::runtime_error {
public: public:
XArch(XArchEval* adoptedEvaluator) : std::runtime_error(""), m_eval(adoptedEvaluator) { } XArch(XArchEval* adopted) : std::runtime_error(adopted->eval()) { delete adopted; }
XArch(const std::string& msg) : std::runtime_error(msg), m_eval(NULL) { } XArch(const std::string& msg) : std::runtime_error(msg) { }
XArch(const XArch& e) : std::runtime_error(e.what()), m_eval(e.m_eval != NULL ? e.m_eval->clone() : NULL) { } ~XArch() _NOEXCEPT { }
~XArch() _NOEXCEPT { delete m_eval; }
virtual const char* what() const _NOEXCEPT;
private:
XArchEval* m_eval;
}; };
// Macro to declare XArch derived types // Macro to declare XArch derived types

View File

@ -24,12 +24,6 @@
// XArchEvalUnix // XArchEvalUnix
// //
XArchEval*
XArchEvalUnix::clone() const throw()
{
return new XArchEvalUnix(m_errno);
}
std::string std::string
XArchEvalUnix::eval() const throw() XArchEvalUnix::eval() const throw()
{ {

View File

@ -23,13 +23,11 @@
//! Lazy error message string evaluation for unix //! Lazy error message string evaluation for unix
class XArchEvalUnix : public XArchEval { class XArchEvalUnix : public XArchEval {
public: public:
XArchEvalUnix(int err) : m_errno(err) { } XArchEvalUnix(int error) : m_error(error) { }
virtual ~XArchEvalUnix() { } virtual ~XArchEvalUnix() { }
// XArchEval overrides virtual std::string eval() const;
virtual XArchEval* clone() const throw();
virtual std::string eval() const throw();
private: private:
int m_errno; int m_error;
}; };

View File

@ -18,17 +18,12 @@
#include "arch/win32/XArchWindows.h" #include "arch/win32/XArchWindows.h"
#include "arch/win32/ArchNetworkWinsock.h" #include "arch/win32/ArchNetworkWinsock.h"
#include "base/String.h"
// //
// XArchEvalWindows // XArchEvalWindows
// //
XArchEval*
XArchEvalWindows::clone() const throw()
{
return new XArchEvalWindows(m_errno);
}
std::string std::string
XArchEvalWindows::eval() const throw() XArchEvalWindows::eval() const throw()
{ {
@ -37,13 +32,13 @@ XArchEvalWindows::eval() const throw()
FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_FROM_SYSTEM,
0, 0,
m_errno, m_error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&cmsg, (LPTSTR)&cmsg,
0, 0,
NULL) == 0) { NULL) == 0) {
cmsg = NULL; cmsg = NULL;
return "Unknown error"; return string_format("Unknown error, code %d", m_error);
} }
std::string smsg(cmsg); std::string smsg(cmsg);
LocalFree(cmsg); LocalFree(cmsg);
@ -55,12 +50,6 @@ XArchEvalWindows::eval() const throw()
// XArchEvalWinsock // XArchEvalWinsock
// //
XArchEval*
XArchEvalWinsock::clone() const throw()
{
return new XArchEvalWinsock(m_errno);
}
std::string std::string
XArchEvalWinsock::eval() const throw() XArchEvalWinsock::eval() const throw()
{ {
@ -123,7 +112,7 @@ XArchEvalWinsock::eval() const throw()
}; };
for (unsigned int i = 0; s_netErrorCodes[i].m_code != 0; ++i) { for (unsigned int i = 0; s_netErrorCodes[i].m_code != 0; ++i) {
if (s_netErrorCodes[i].m_code == m_errno) { if (s_netErrorCodes[i].m_code == m_error) {
return s_netErrorCodes[i].m_msg; return s_netErrorCodes[i].m_msg;
} }
} }

View File

@ -26,28 +26,24 @@
//! Lazy error message string evaluation for windows //! Lazy error message string evaluation for windows
class XArchEvalWindows : public XArchEval { class XArchEvalWindows : public XArchEval {
public: public:
XArchEvalWindows() : m_errno(GetLastError()) { } XArchEvalWindows() : m_error(GetLastError()) { }
XArchEvalWindows(DWORD err) : m_errno(err) { } XArchEvalWindows(DWORD error) : m_error(error) { }
virtual ~XArchEvalWindows() { } virtual ~XArchEvalWindows() { }
// XArchEval overrides virtual std::string eval() const;
virtual XArchEval* clone() const throw();
virtual std::string eval() const throw();
private: private:
DWORD m_errno; DWORD m_error;
}; };
//! Lazy error message string evaluation for winsock //! Lazy error message string evaluation for winsock
class XArchEvalWinsock : public XArchEval { class XArchEvalWinsock : public XArchEval {
public: public:
XArchEvalWinsock(int err) : m_errno(err) { } XArchEvalWinsock(int error) : m_error(error) { }
virtual ~XArchEvalWinsock() { } virtual ~XArchEvalWinsock() { }
// XArchEval overrides virtual std::string eval() const;
virtual XArchEval* clone() const throw();
virtual std::string eval() const throw();
private: private:
int m_errno; int m_error;
}; };

View File

@ -17,6 +17,9 @@
#include "base/String.h" #include "base/String.h"
#include <memory>
#include <cstdarg>
void void
find_replace_all( find_replace_all(
CString& subject, CString& subject,
@ -29,3 +32,34 @@ find_replace_all(
pos += replace.length(); pos += replace.length();
} }
} }
CString
string_format(const CString format, ...)
{
// reserve 2 times as much as the length of the format
size_t final, n = format.size() * 2;
CString str;
std::unique_ptr<char[]> formatted;
va_list ap;
while (true) {
// wrap the plain char array in unique_ptr
formatted.reset(new char[n]);
strcpy(&formatted[0], format.c_str());
va_start(ap, format);
final = vsnprintf(&formatted[0], n, format.c_str(), ap);
va_end(ap);
if (final < 0 || final >= n) {
n += abs(static_cast<int>(final - n + 1));
}
else {
break;
}
}
return CString(formatted.get());
}

View File

@ -25,3 +25,4 @@
typedef std::string CString; typedef std::string CString;
void find_replace_all(CString& subject, const CString& find, const CString& replace); void find_replace_all(CString& subject, const CString& find, const CString& replace);
CString string_format(const CString format, ...);