mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-09 12:32:02 +00:00
Fix bug #20205
Malformed data caused config::error exception to be thrown. Unfortunately campaignd on catching such an exception had no way to close the right connection, instead all connections were closed because the local variable that was supposed to contain connection number wasn't updated. This is fixed by using boost.exception to attach the necessary data to config::error objects so it can be used at the catch site.
This commit is contained in:
parent
98a9b7ad9d
commit
136f42bd4f
@ -36,6 +36,7 @@
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/iostreams/filter/gzip.hpp>
|
||||
#include <boost/exception/get_error_info.hpp>
|
||||
|
||||
// the fork execute is unix specific only tested on Linux quite sure it won't
|
||||
// work on Windows not sure which other platforms have a problem with it.
|
||||
@ -571,9 +572,20 @@ namespace {
|
||||
LOG_CS << "client disconnect: " << e.message << " " << network::ip_address(e.socket) << "\n";
|
||||
e.disconnect();
|
||||
}
|
||||
} catch(config::error& /*e*/) {
|
||||
LOG_CS << "error in receiving data...\n";
|
||||
network::disconnect(sock);
|
||||
} catch(const config::error& e) {
|
||||
network::connection err_sock = 0;
|
||||
network::connection const * err_connection = boost::get_error_info<network::connection_info>(e);
|
||||
if(err_connection != NULL) {
|
||||
err_sock = *err_connection;
|
||||
}
|
||||
if(err_sock == 0 && sock > 0)
|
||||
err_sock = sock;
|
||||
if(err_sock) {
|
||||
LOG_CS << "client disconnect due to exception: " << e.what() << " " << network::ip_address(*err_connection) << "\n";
|
||||
network::disconnect(*err_connection);
|
||||
} else {
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Delay(20);
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <iosfwd>
|
||||
#include <vector>
|
||||
#include <boost/variant/variant.hpp>
|
||||
#include <boost/exception/exception.hpp>
|
||||
|
||||
#include "game_errors.hpp"
|
||||
#include "tstring.hpp"
|
||||
@ -397,7 +398,7 @@ public:
|
||||
std::string debug() const;
|
||||
std::string hash() const;
|
||||
|
||||
struct error : public game::error {
|
||||
struct error : public game::error, public boost::exception {
|
||||
error(const std::string& message) : game::error(message) {}
|
||||
};
|
||||
|
||||
|
@ -38,6 +38,9 @@
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <boost/exception/get_error_info.hpp>
|
||||
#include <boost/exception/info.hpp>
|
||||
|
||||
#include <signal.h>
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
|
||||
#undef INADDR_ANY
|
||||
@ -795,7 +798,23 @@ connection receive_data(config& cfg, connection connection_num, bandwidth_in_ptr
|
||||
{
|
||||
bandwidth_in = &temp;
|
||||
}
|
||||
sock = network_worker_pool::get_received_data(sock,cfg, *bandwidth_in);
|
||||
try {
|
||||
sock = network_worker_pool::get_received_data(sock,cfg, *bandwidth_in);
|
||||
} catch(const config::error& e) {
|
||||
TCPsocket const * err_sock = boost::get_error_info<tcpsocket_info>(e);
|
||||
if(err_sock == NULL)
|
||||
throw;
|
||||
connection err_connection = 0;
|
||||
for(connection_map::const_iterator i = connections.begin(); i != connections.end(); ++i) {
|
||||
if(i->second.sock == *err_sock) {
|
||||
err_connection = i->first;
|
||||
}
|
||||
}
|
||||
if(err_connection) {
|
||||
throw e << connection_info(err_connection);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
if (sock == NULL) {
|
||||
if (!is_server() && last_ping != 0 && ping_timeout != 0)
|
||||
{
|
||||
|
@ -30,6 +30,7 @@ class config;
|
||||
#include <vector>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/exception/error_info.hpp>
|
||||
|
||||
namespace threading
|
||||
{
|
||||
@ -267,6 +268,9 @@ struct error : public game::error
|
||||
void disconnect();
|
||||
};
|
||||
|
||||
typedef boost::error_info<struct tag_tcpsocket,TCPsocket> tcpsocket_info;
|
||||
typedef boost::error_info<struct tag_connum,connection> connection_info;
|
||||
|
||||
struct statistics
|
||||
{
|
||||
statistics() : total(0), current(0), current_max(0) {}
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "wesconfig.h"
|
||||
|
||||
#include <boost/iostreams/filter/gzip.hpp>
|
||||
#include <boost/exception/info.hpp>
|
||||
|
||||
#include <cerrno>
|
||||
#include <deque>
|
||||
@ -918,9 +919,10 @@ TCPsocket get_received_data(TCPsocket sock, config& cfg, network::bandwidth_in_p
|
||||
// throw the error in parent thread
|
||||
std::string error = (*itor)->config_error;
|
||||
buffer* buf = *itor;
|
||||
TCPsocket err_sock = (*itor)->sock;
|
||||
received_data_queue.erase(itor);
|
||||
delete buf;
|
||||
throw config::error(error);
|
||||
throw config::error(error) << network::tcpsocket_info(err_sock);
|
||||
} else {
|
||||
cfg.swap((*itor)->config_buf);
|
||||
const TCPsocket res = (*itor)->sock;
|
||||
|
Loading…
x
Reference in New Issue
Block a user