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. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -36,7 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/version.hpp> #include <boost/version.hpp>
#include "libtorrent/config.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 // asio assumes that the windows error codes are defined already
#include <winsock2.h> #include <winsock2.h>
#endif #endif
@ -50,6 +50,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/string_util.hpp" // for allocate_string_copy #include "libtorrent/string_util.hpp" // for allocate_string_copy
#include <stdlib.h> // free #include <stdlib.h> // free
#ifndef BOOST_SYSTEM_NOEXCEPT
#define BOOST_SYSTEM_NOEXCEPT throw()
#endif
namespace libtorrent namespace libtorrent
{ {
@ -265,6 +269,7 @@ namespace libtorrent
expected_value, expected_value,
depth_exceeded, depth_exceeded,
limit_exceeded, limit_exceeded,
overflow,
error_code_max error_code_max
}; };
@ -310,20 +315,16 @@ namespace libtorrent
#if BOOST_VERSION < 103500 #if BOOST_VERSION < 103500
typedef asio::error_code error_code; typedef asio::error_code error_code;
// hidden
inline asio::error::error_category get_posix_category() { return asio::error::system_category; } 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; } inline asio::error::error_category get_system_category() { return asio::error::system_category; }
// hidden inline boost::system::error_category const& get_libtorrent_category()
boost::system::error_category const& get_libtorrent_category()
{ {
static ::asio::error::error_category libtorrent_category(20); static ::asio::error::error_category libtorrent_category(20);
return libtorrent_category; return libtorrent_category;
} }
// hidden inline boost::system::error_category const& get_http_category()
boost::system::error_category const& get_http_category()
{ {
static ::asio::error::error_category http_category(21); static ::asio::error::error_category http_category(21);
return http_category; return http_category;
@ -333,26 +334,26 @@ namespace libtorrent
struct TORRENT_EXPORT libtorrent_error_category : boost::system::error_category struct TORRENT_EXPORT libtorrent_error_category : boost::system::error_category
{ {
virtual const char* name() const throw(); virtual const char* name() const BOOST_SYSTEM_NOEXCEPT;
virtual std::string message(int ev) const throw(); virtual std::string message(int ev) const BOOST_SYSTEM_NOEXCEPT;
virtual boost::system::error_condition default_error_condition(int ev) const throw() virtual boost::system::error_condition default_error_condition(int ev) const BOOST_SYSTEM_NOEXCEPT
{ 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()
{ return boost::system::error_condition(ev, *this); } { return boost::system::error_condition(ev, *this); }
}; };
TORRENT_EXPORT boost::system::error_category& get_libtorrent_category(); 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(); TORRENT_EXPORT boost::system::error_category& get_http_category();
namespace errors namespace errors
{ {
// hidden
inline boost::system::error_code make_error_code(error_code_enum e) inline boost::system::error_code make_error_code(error_code_enum e)
{ {
return boost::system::error_code(e, get_libtorrent_category()); return boost::system::error_code(e, get_libtorrent_category());
@ -361,15 +362,14 @@ namespace libtorrent
using boost::system::error_code; using boost::system::error_code;
// hidden
inline boost::system::error_category const& get_system_category()
#if BOOST_VERSION < 104400 #if BOOST_VERSION < 104400
inline boost::system::error_category const& get_system_category()
{ return boost::system::get_system_category(); } { return boost::system::get_system_category(); }
#else #else
inline boost::system::error_category const& get_system_category()
{ return boost::system::system_category(); } { return boost::system::system_category(); }
#endif #endif
// hidden
inline boost::system::error_category const& get_posix_category() inline boost::system::error_category const& get_posix_category()
#if BOOST_VERSION < 103600 #if BOOST_VERSION < 103600
{ return boost::system::get_posix_category(); } { 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. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <vector> #include <vector>
#include <string> #include <string>
#include <cstring> #include <cstring>
#include <algorithm>
#include "libtorrent/config.hpp" #include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp" #include "libtorrent/assert.hpp"
#include "libtorrent/size_type.hpp" #include "libtorrent/size_type.hpp"
@ -50,6 +51,9 @@ namespace libtorrent
{ {
struct lazy_entry; struct lazy_entry;
TORRENT_EXPORT char const* parse_int(char const* start, char const* end
, char delimiter, boost::int64_t& val);
// return 0 = success // return 0 = success
TORRENT_EXPORT int lazy_bdecode(char const* start, char const* end TORRENT_EXPORT int lazy_bdecode(char const* start, char const* end
, lazy_entry& ret, error_code& ec, int* error_pos = 0 , 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; , lazy_entry& ret, int depth_limit = 1000, int item_limit = 1000000) TORRENT_DEPRECATED;
#endif #endif
struct TORRENT_EXPORT pascal_string struct pascal_string
{ {
pascal_string(char const* p, int l): len(l), ptr(p) {} pascal_string(char const* p, int l): len(l), ptr(p) {}
int len; int len;
@ -156,11 +160,15 @@ namespace libtorrent
lazy_entry* dict_find(char const* name); lazy_entry* dict_find(char const* name);
lazy_entry const* dict_find(char const* name) const lazy_entry const* dict_find(char const* name) const
{ return const_cast<lazy_entry*>(this)->dict_find(name); } { 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; std::string dict_find_string_value(char const* name) const;
pascal_string dict_find_pstr(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; 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(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_list(char const* name) const;
lazy_entry const* dict_find_string(char const* name) const; lazy_entry const* dict_find_string(char const* name) const;
lazy_entry const* dict_find_int(char const* name) const; lazy_entry const* dict_find_int(char const* name) const;
@ -279,8 +287,12 @@ namespace libtorrent
lazy_entry val; 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); , 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. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -40,12 +40,12 @@ namespace libtorrent
{ {
#if BOOST_VERSION >= 103500 #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"; 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[] = static char const* msgs[] =
{ {
@ -257,30 +257,19 @@ namespace libtorrent
"expected value (list, dict, int or string) in bencoded string", "expected value (list, dict, int or string) in bencoded string",
"bencoded nesting depth exceeded", "bencoded nesting depth exceeded",
"bencoded item count limit exceeded", "bencoded item count limit exceeded",
"integer overflow",
}; };
if (ev < 0 || ev >= int(sizeof(msgs)/sizeof(msgs[0]))) if (ev < 0 || ev >= int(sizeof(msgs)/sizeof(msgs[0])))
return "Unknown error"; return "Unknown error";
return msgs[ev]; return msgs[ev];
} }
boost::system::error_category& get_libtorrent_category() const char* http_error_category::name() const BOOST_SYSTEM_NOEXCEPT
{
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()
{ {
return "http error"; 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; std::string ret;
ret += to_string(ev).elems; ret += to_string(ev).elems;
@ -308,6 +297,19 @@ namespace libtorrent
} }
return ret; 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 #endif
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS

View File

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