sync lazy_bdecode to 0.16 branch before applying security fix

This commit is contained in:
Miguel Freitas 2015-10-18 19:38:36 -02:00
parent 9a5d0cc45c
commit 33a4e14941
4 changed files with 133 additions and 55 deletions

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2008-2012, Arvid Norberg
Copyright (c) 2008, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -36,7 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/version.hpp>
#include "libtorrent/config.hpp"
#if defined TORRENT_WINDOWS
#if defined TORRENT_WINDOWS || defined TORRENT_CYGWIN
// asio assumes that the windows error codes are defined already
#include <winsock2.h>
#endif
@ -50,6 +50,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/string_util.hpp" // for allocate_string_copy
#include <stdlib.h> // free
#ifndef BOOST_SYSTEM_NOEXCEPT
#define BOOST_SYSTEM_NOEXCEPT throw()
#endif
namespace libtorrent
{
@ -265,6 +269,7 @@ namespace libtorrent
expected_value,
depth_exceeded,
limit_exceeded,
overflow,
error_code_max
};
@ -310,20 +315,16 @@ namespace libtorrent
#if BOOST_VERSION < 103500
typedef asio::error_code error_code;
// hidden
inline asio::error::error_category get_posix_category() { return asio::error::system_category; }
// hidden
inline asio::error::error_category get_system_category() { return asio::error::system_category; }
// hidden
boost::system::error_category const& get_libtorrent_category()
inline boost::system::error_category const& get_libtorrent_category()
{
static ::asio::error::error_category libtorrent_category(20);
return libtorrent_category;
}
// hidden
boost::system::error_category const& get_http_category()
inline boost::system::error_category const& get_http_category()
{
static ::asio::error::error_category http_category(21);
return http_category;
@ -333,26 +334,26 @@ namespace libtorrent
struct TORRENT_EXPORT libtorrent_error_category : boost::system::error_category
{
virtual const char* name() const throw();
virtual std::string message(int ev) const throw();
virtual boost::system::error_condition default_error_condition(int ev) const throw()
{ return boost::system::error_condition(ev, *this); }
};
struct TORRENT_EXPORT http_error_category : boost::system::error_category
{
virtual const char* name() const throw();
virtual std::string message(int ev) const throw();
virtual boost::system::error_condition default_error_condition(int ev) const throw()
virtual const char* name() const BOOST_SYSTEM_NOEXCEPT;
virtual std::string message(int ev) const BOOST_SYSTEM_NOEXCEPT;
virtual boost::system::error_condition default_error_condition(int ev) const BOOST_SYSTEM_NOEXCEPT
{ return boost::system::error_condition(ev, *this); }
};
TORRENT_EXPORT boost::system::error_category& get_libtorrent_category();
struct TORRENT_EXPORT http_error_category : boost::system::error_category
{
virtual const char* name() const BOOST_SYSTEM_NOEXCEPT;
virtual std::string message(int ev) const BOOST_SYSTEM_NOEXCEPT;
virtual boost::system::error_condition default_error_condition(int ev) const BOOST_SYSTEM_NOEXCEPT
{ return boost::system::error_condition(ev, *this); }
};
TORRENT_EXPORT boost::system::error_category& get_http_category();
namespace errors
{
// hidden
inline boost::system::error_code make_error_code(error_code_enum e)
{
return boost::system::error_code(e, get_libtorrent_category());
@ -361,15 +362,14 @@ namespace libtorrent
using boost::system::error_code;
// hidden
inline boost::system::error_category const& get_system_category()
#if BOOST_VERSION < 104400
inline boost::system::error_category const& get_system_category()
{ return boost::system::get_system_category(); }
#else
inline boost::system::error_category const& get_system_category()
{ return boost::system::system_category(); }
#endif
// hidden
inline boost::system::error_category const& get_posix_category()
#if BOOST_VERSION < 103600
{ return boost::system::get_posix_category(); }

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2003-2012, Arvid Norberg
Copyright (c) 2003, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"
#include "libtorrent/size_type.hpp"
@ -50,6 +51,9 @@ namespace libtorrent
{
struct lazy_entry;
TORRENT_EXPORT char const* parse_int(char const* start, char const* end
, char delimiter, boost::int64_t& val);
// return 0 = success
TORRENT_EXPORT int lazy_bdecode(char const* start, char const* end
, lazy_entry& ret, error_code& ec, int* error_pos = 0
@ -63,7 +67,7 @@ namespace libtorrent
, lazy_entry& ret, int depth_limit = 1000, int item_limit = 1000000) TORRENT_DEPRECATED;
#endif
struct TORRENT_EXPORT pascal_string
struct pascal_string
{
pascal_string(char const* p, int l): len(l), ptr(p) {}
int len;
@ -156,11 +160,15 @@ namespace libtorrent
lazy_entry* dict_find(char const* name);
lazy_entry const* dict_find(char const* name) const
{ return const_cast<lazy_entry*>(this)->dict_find(name); }
lazy_entry* dict_find(std::string const& name);
lazy_entry const* dict_find(std::string const& name) const
{ return const_cast<lazy_entry*>(this)->dict_find(name); }
std::string dict_find_string_value(char const* name) const;
pascal_string dict_find_pstr(char const* name) const;
size_type dict_find_int_value(char const* name, size_type default_val = 0) const;
lazy_entry const* dict_find_dict(char const* name) const;
lazy_entry const* dict_find_dict(std::string const& name) const;
lazy_entry const* dict_find_list(char const* name) const;
lazy_entry const* dict_find_string(char const* name) const;
lazy_entry const* dict_find_int(char const* name) const;
@ -279,8 +287,12 @@ namespace libtorrent
lazy_entry val;
};
TORRENT_EXTRA_EXPORT std::string print_entry(lazy_entry const& e
TORRENT_EXPORT std::string print_entry(lazy_entry const& e
, bool single_line = false, int indent = 0);
#if TORRENT_USE_IOSTREAM
TORRENT_EXPORT std::ostream& operator<<(std::ostream& os, lazy_entry const& e);
#endif
}

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2008-2012, Arvid Norberg
Copyright (c) 2008, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -40,12 +40,12 @@ namespace libtorrent
{
#if BOOST_VERSION >= 103500
const char* libtorrent_error_category::name() const throw()
const char* libtorrent_error_category::name() const BOOST_SYSTEM_NOEXCEPT
{
return "libtorrent error";
}
std::string libtorrent_error_category::message(int ev) const throw()
std::string libtorrent_error_category::message(int ev) const BOOST_SYSTEM_NOEXCEPT
{
static char const* msgs[] =
{
@ -257,30 +257,19 @@ namespace libtorrent
"expected value (list, dict, int or string) in bencoded string",
"bencoded nesting depth exceeded",
"bencoded item count limit exceeded",
"integer overflow",
};
if (ev < 0 || ev >= int(sizeof(msgs)/sizeof(msgs[0])))
return "Unknown error";
return msgs[ev];
}
boost::system::error_category& get_libtorrent_category()
{
static libtorrent_error_category libtorrent_category;
return libtorrent_category;
}
boost::system::error_category& get_http_category()
{
static http_error_category http_category;
return http_category;
}
const char* http_error_category::name() const throw()
const char* http_error_category::name() const BOOST_SYSTEM_NOEXCEPT
{
return "http error";
}
std::string http_error_category::message(int ev) const throw()
std::string http_error_category::message(int ev) const BOOST_SYSTEM_NOEXCEPT
{
std::string ret;
ret += to_string(ev).elems;
@ -308,6 +297,19 @@ namespace libtorrent
}
return ret;
}
boost::system::error_category& get_libtorrent_category()
{
static libtorrent_error_category libtorrent_category;
return libtorrent_category;
}
boost::system::error_category& get_http_category()
{
static http_error_category http_category;
return http_category;
}
#endif
#ifndef BOOST_NO_EXCEPTIONS

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2008-2012, Arvid Norberg
Copyright (c) 2008, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
*/
#include "libtorrent/config.hpp"
#include "libtorrent/lazy_entry.hpp"
#include "libtorrent/escape_string.hpp"
#include <cstring>
@ -63,15 +64,33 @@ namespace libtorrent
// first occurance of the delimiter is interpreted as an int.
// return the pointer to the delimiter, or 0 if there is a
// parse error. val should be initialized to zero
char const* parse_int(char const* start, char const* end, char delimiter, boost::int64_t& val)
char const* parse_int(char const* start, char const* end, char delimiter
, boost::int64_t& val, error_code& ec)
{
while (start < end && *start != delimiter)
{
if (!is_digit(*start)) { return 0; }
if (!is_digit(*start))
{
ec = errors::expected_string;
return start;
}
if (val > INT64_MAX / 10)
{
ec = errors::overflow;
return start;
}
val *= 10;
val += *start - '0';
int digit = *start - '0';
if (val > INT64_MAX - digit)
{
ec = errors::overflow;
return start;
}
val += digit;
++start;
}
if (*start != delimiter)
ec = errors::expected_colon;
return start;
}
@ -126,9 +145,17 @@ namespace libtorrent
}
if (!is_digit(t)) TORRENT_FAIL_BDECODE(errors::expected_string);
boost::int64_t len = t - '0';
start = parse_int(start, end, ':', len);
if (start == 0 || start + len + 3 > end || *start != ':')
TORRENT_FAIL_BDECODE(errors::expected_colon);
error_code e;
start = parse_int(start, end, ':', len, e);
if (e)
TORRENT_FAIL_BDECODE(e);
if (start + len + 1 > end)
TORRENT_FAIL_BDECODE(errors::unexpected_eof);
if (len < 0)
TORRENT_FAIL_BDECODE(errors::overflow);
++start;
if (start == end) TORRENT_FAIL_BDECODE(errors::unexpected_eof);
lazy_entry* ent = top->dict_append(start);
@ -185,9 +212,15 @@ namespace libtorrent
TORRENT_FAIL_BDECODE(errors::expected_value);
boost::int64_t len = t - '0';
start = parse_int(start, end, ':', len);
if (start == 0 || start + len + 1 > end || *start != ':')
TORRENT_FAIL_BDECODE(errors::expected_colon);
error_code e;
start = parse_int(start, end, ':', len, e);
if (e)
TORRENT_FAIL_BDECODE(e);
if (start + len + 1 > end)
TORRENT_FAIL_BDECODE(errors::unexpected_eof);
if (len < 0)
TORRENT_FAIL_BDECODE(errors::overflow);
++start;
top->construct_string(start, int(len));
stack.pop_back();
@ -206,7 +239,10 @@ namespace libtorrent
boost::int64_t val = 0;
bool negative = false;
if (*m_data.start == '-') negative = true;
parse_int(negative?m_data.start+1:m_data.start, m_data.start + m_size, 'e', val);
error_code ec;
parse_int(m_data.start + negative
, m_data.start + m_size, 'e', val, ec);
if (ec) return 0;
if (negative) val = -val;
return val;
}
@ -339,6 +375,13 @@ namespace libtorrent
return e;
}
lazy_entry const* lazy_entry::dict_find_dict(std::string const& name) const
{
lazy_entry const* e = dict_find(name);
if (e == 0 || e->type() != lazy_entry::dict_t) return 0;
return e;
}
lazy_entry const* lazy_entry::dict_find_list(char const* name) const
{
lazy_entry const* e = dict_find(name);
@ -358,6 +401,20 @@ namespace libtorrent
return 0;
}
lazy_entry* lazy_entry::dict_find(std::string const& name)
{
TORRENT_ASSERT(m_type == dict_t);
for (int i = 0; i < int(m_size); ++i)
{
lazy_dict_entry& e = m_data.dict[i];
if (name.size() != e.val.m_begin - e.name) continue;
if (std::equal(name.begin(), name.end(), e.name))
return &e.val;
}
return 0;
}
lazy_entry* lazy_entry::list_append()
{
TORRENT_ASSERT(m_type == list_t);
@ -426,6 +483,13 @@ namespace libtorrent
return return_t(m_begin, m_len);
}
#if TORRENT_USE_IOSTREAM
std::ostream& operator<<(std::ostream& os, lazy_entry const& e)
{
return os << print_entry(e);
}
#endif // TORRENT_USE_IOSTREAM
int line_longer_than(lazy_entry const& e, int limit)
{
int line_len = 0;
@ -491,7 +555,7 @@ namespace libtorrent
case lazy_entry::int_t:
{
char str[100];
snprintf(str, sizeof(str), "%"PRId64, e.int_value());
snprintf(str, sizeof(str), "%" PRId64, e.int_value());
return str;
}
case lazy_entry::string_t: