mirror of
https://github.com/boostorg/system.git
synced 2025-07-31 13:07:13 +02:00
Fix #3474, memory leak on exception. First reported by Chis Kohlhoff.
[SVN r63184]
This commit is contained in:
@@ -29,6 +29,7 @@ using namespace boost::system::errc;
|
|||||||
|
|
||||||
# if defined( BOOST_WINDOWS_API )
|
# if defined( BOOST_WINDOWS_API )
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
# include "local_free_on_destruction.hpp"
|
||||||
# ifndef ERROR_INCORRECT_SIZE
|
# ifndef ERROR_INCORRECT_SIZE
|
||||||
# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS
|
# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS
|
||||||
# endif
|
# endif
|
||||||
@@ -340,25 +341,11 @@ namespace
|
|||||||
return generic_category().message( ev );
|
return generic_category().message( ev );
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
// TODO:
|
|
||||||
|
|
||||||
//Some quick notes on the implementation (sorry for the noise if
|
|
||||||
//someone has already mentioned them):
|
|
||||||
//
|
|
||||||
//- The ::LocalFree() usage isn't exception safe.
|
|
||||||
//
|
|
||||||
//See:
|
|
||||||
//
|
|
||||||
//<http://boost.cvs.sourceforge.net/boost/boost/boost/asio/system_exception.hpp?revision=1.1&view=markup>
|
|
||||||
//
|
|
||||||
//in the implementation of what() for an example.
|
|
||||||
//
|
|
||||||
//Cheers,
|
|
||||||
//Chris
|
|
||||||
std::string system_error_category::message( int ev ) const
|
std::string system_error_category::message( int ev ) const
|
||||||
{
|
{
|
||||||
# ifndef BOOST_NO_ANSI_APIS
|
# ifndef BOOST_NO_ANSI_APIS
|
||||||
LPVOID lpMsgBuf;
|
LPVOID lpMsgBuf = 0;
|
||||||
DWORD retval = ::FormatMessageA(
|
DWORD retval = ::FormatMessageA(
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
@@ -370,13 +357,13 @@ namespace
|
|||||||
0,
|
0,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
detail::local_free_on_destruction lfod(lpMsgBuf);
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
return std::string("Unknown error");
|
return std::string("Unknown error");
|
||||||
|
|
||||||
std::string str( static_cast<LPCSTR>(lpMsgBuf) );
|
std::string str( static_cast<LPCSTR>(lpMsgBuf) );
|
||||||
::LocalFree( lpMsgBuf ); // free the buffer
|
|
||||||
# else // WinCE workaround
|
# else // WinCE workaround
|
||||||
LPVOID lpMsgBuf;
|
LPVOID lpMsgBuf = 0;
|
||||||
DWORD retval = ::FormatMessageW(
|
DWORD retval = ::FormatMessageW(
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
@@ -388,6 +375,7 @@ namespace
|
|||||||
0,
|
0,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
detail::local_free_on_destruction lfod(lpMsgBuf);
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
return std::string("Unknown error");
|
return std::string("Unknown error");
|
||||||
|
|
||||||
@@ -397,7 +385,6 @@ namespace
|
|||||||
return std::string("Unknown error");
|
return std::string("Unknown error");
|
||||||
|
|
||||||
std::string str( narrow_buffer );
|
std::string str( narrow_buffer );
|
||||||
::LocalFree( lpMsgBuf ); // free the buffer
|
|
||||||
# endif
|
# endif
|
||||||
while ( str.size()
|
while ( str.size()
|
||||||
&& (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
|
&& (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
|
||||||
|
40
src/local_free_on_destruction.hpp
Normal file
40
src/local_free_on_destruction.hpp
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// local_free_on_exit.hpp ------------------------------------------------------------//
|
||||||
|
|
||||||
|
// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
// Copyright (c) 2010 Beman Dawes
|
||||||
|
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// See http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
|
// This is derived from boost/asio/detail/local_free_on_block_exit.hpp to avoid
|
||||||
|
// a dependency on asio. Thanks to Chris Kohlhoff for pointing it out.
|
||||||
|
|
||||||
|
#ifndef BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP
|
||||||
|
#define BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace system {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
class local_free_on_destruction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit local_free_on_destruction(void* p)
|
||||||
|
: p_(p) {}
|
||||||
|
|
||||||
|
~local_free_on_destruction()
|
||||||
|
{
|
||||||
|
::LocalFree(p_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* p_;
|
||||||
|
local_free_on_destruction(const local_free_on_destruction&); // = deleted
|
||||||
|
local_free_on_destruction& operator=(const local_free_on_destruction&); // = deleted
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace system
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP
|
Reference in New Issue
Block a user