break out bdecode errors into its own category
This commit is contained in:
parent
4e94ae592c
commit
0158710f5c
|
@ -416,7 +416,7 @@ namespace libtorrent
|
|||
// invalid action field in udp tracker response
|
||||
invalid_tracker_action,
|
||||
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
// expected string in bencoded string
|
||||
expected_string = 190,
|
||||
// expected colon in bencoded string
|
||||
|
@ -429,6 +429,7 @@ namespace libtorrent
|
|||
depth_exceeded,
|
||||
// bencoded item count limit exceeded
|
||||
limit_exceeded,
|
||||
#endif
|
||||
|
||||
// the number of error codes
|
||||
error_code_max
|
||||
|
@ -498,14 +499,6 @@ namespace libtorrent
|
|||
|
||||
#else
|
||||
|
||||
struct TORRENT_EXPORT libtorrent_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); }
|
||||
};
|
||||
|
||||
struct TORRENT_EXPORT http_error_category : boost::system::error_category
|
||||
{
|
||||
virtual const char* name() const BOOST_SYSTEM_NOEXCEPT;
|
||||
|
|
|
@ -367,8 +367,41 @@ namespace libtorrent
|
|||
|
||||
TORRENT_EXTRA_EXPORT std::string print_entry(lazy_entry const& e
|
||||
, bool single_line = false, int indent = 0);
|
||||
}
|
||||
|
||||
TORRENT_EXPORT boost::system::error_category& get_bdecode_category();
|
||||
|
||||
namespace bdecode_errors
|
||||
{
|
||||
// libtorrent uses boost.system's ``error_code`` class to represent errors. libtorrent has
|
||||
// its own error category get_bdecode_category() whith the error codes defined by error_code_enum.
|
||||
enum error_code_enum
|
||||
{
|
||||
// Not an error
|
||||
no_error = 0,
|
||||
// expected string in bencoded string
|
||||
expected_string,
|
||||
// expected colon in bencoded string
|
||||
expected_colon,
|
||||
// unexpected end of file in bencoded string
|
||||
unexpected_eof,
|
||||
// expected value (list, dict, int or string) in bencoded string
|
||||
expected_value,
|
||||
// bencoded recursion depth limit exceeded
|
||||
depth_exceeded,
|
||||
// bencoded item count limit exceeded
|
||||
limit_exceeded,
|
||||
|
||||
// the number of error codes
|
||||
error_code_max
|
||||
};
|
||||
|
||||
// hidden
|
||||
inline boost::system::error_code make_error_code(error_code_enum e)
|
||||
{
|
||||
return boost::system::error_code(e, get_bdecode_category());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -40,6 +40,14 @@ namespace libtorrent
|
|||
{
|
||||
#if BOOST_VERSION >= 103500
|
||||
|
||||
struct libtorrent_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); }
|
||||
};
|
||||
|
||||
const char* libtorrent_error_category::name() const BOOST_SYSTEM_NOEXCEPT
|
||||
{
|
||||
return "libtorrent error";
|
||||
|
@ -239,6 +247,7 @@ namespace libtorrent
|
|||
"udp tracker response packet has invalid size",
|
||||
"invalid transaction id in udp tracker response",
|
||||
"invalid action field in udp tracker response",
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
|
@ -257,6 +266,7 @@ namespace libtorrent
|
|||
"expected value (list, dict, int or string) in bencoded string",
|
||||
"bencoded nesting depth exceeded",
|
||||
"bencoded item count limit exceeded",
|
||||
#endif
|
||||
};
|
||||
if (ev < 0 || ev >= int(sizeof(msgs)/sizeof(msgs[0])))
|
||||
return "Unknown error";
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace libtorrent
|
|||
|
||||
#define TORRENT_FAIL_BDECODE(code) \
|
||||
{ \
|
||||
ec = code; \
|
||||
ec = make_error_code(code); \
|
||||
while (!stack.empty()) { \
|
||||
top = stack.back(); \
|
||||
if (top->type() == lazy_entry::dict_t || top->type() == lazy_entry::list_t) top->pop(); \
|
||||
|
@ -103,11 +103,11 @@ namespace libtorrent
|
|||
|
||||
lazy_entry* top = stack.back();
|
||||
|
||||
if (int(stack.size()) > depth_limit) TORRENT_FAIL_BDECODE(errors::depth_exceeded);
|
||||
if (start >= end) TORRENT_FAIL_BDECODE(errors::unexpected_eof);
|
||||
if (int(stack.size()) > depth_limit) TORRENT_FAIL_BDECODE(bdecode_errors::depth_exceeded);
|
||||
if (start >= end) TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof);
|
||||
char t = *start;
|
||||
++start;
|
||||
if (start >= end && t != 'e') TORRENT_FAIL_BDECODE(errors::unexpected_eof);
|
||||
if (start >= end && t != 'e') TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof);
|
||||
|
||||
switch (top->type())
|
||||
{
|
||||
|
@ -119,17 +119,17 @@ namespace libtorrent
|
|||
stack.pop_back();
|
||||
continue;
|
||||
}
|
||||
if (!is_digit(t)) TORRENT_FAIL_BDECODE(errors::expected_string);
|
||||
if (!is_digit(t)) TORRENT_FAIL_BDECODE(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);
|
||||
TORRENT_FAIL_BDECODE(bdecode_errors::expected_colon);
|
||||
++start;
|
||||
if (start == end) TORRENT_FAIL_BDECODE(errors::unexpected_eof);
|
||||
if (start == end) TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof);
|
||||
lazy_entry* ent = top->dict_append(start);
|
||||
if (ent == 0) TORRENT_FAIL_BDECODE(errors::no_memory);
|
||||
if (ent == 0) TORRENT_FAIL_BDECODE(boost::system::errc::not_enough_memory);
|
||||
start += len;
|
||||
if (start >= end) TORRENT_FAIL_BDECODE(errors::unexpected_eof);
|
||||
if (start >= end) TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof);
|
||||
stack.push_back(ent);
|
||||
t = *start;
|
||||
++start;
|
||||
|
@ -144,7 +144,7 @@ namespace libtorrent
|
|||
continue;
|
||||
}
|
||||
lazy_entry* ent = top->list_append();
|
||||
if (ent == 0) TORRENT_FAIL_BDECODE(errors::no_memory);
|
||||
if (ent == 0) TORRENT_FAIL_BDECODE(boost::system::errc::not_enough_memory);
|
||||
stack.push_back(ent);
|
||||
break;
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
--item_limit;
|
||||
if (item_limit <= 0) TORRENT_FAIL_BDECODE(errors::limit_exceeded);
|
||||
if (item_limit <= 0) TORRENT_FAIL_BDECODE(bdecode_errors::limit_exceeded);
|
||||
|
||||
top = stack.back();
|
||||
switch (t)
|
||||
|
@ -168,7 +168,7 @@ namespace libtorrent
|
|||
char const* int_start = start;
|
||||
start = find_char(start, end, 'e');
|
||||
top->construct_int(int_start, start - int_start);
|
||||
if (start == end) TORRENT_FAIL_BDECODE(errors::unexpected_eof);
|
||||
if (start == end) TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof);
|
||||
TORRENT_ASSERT(*start == 'e');
|
||||
++start;
|
||||
stack.pop_back();
|
||||
|
@ -177,12 +177,12 @@ namespace libtorrent
|
|||
default:
|
||||
{
|
||||
if (!is_digit(t))
|
||||
TORRENT_FAIL_BDECODE(errors::expected_value);
|
||||
TORRENT_FAIL_BDECODE(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);
|
||||
TORRENT_FAIL_BDECODE(bdecode_errors::expected_colon);
|
||||
++start;
|
||||
top->construct_string(start, int(len));
|
||||
stack.pop_back();
|
||||
|
@ -555,5 +555,42 @@ namespace libtorrent
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct bdecode_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); }
|
||||
};
|
||||
|
||||
const char* bdecode_error_category::name() const BOOST_SYSTEM_NOEXCEPT
|
||||
{
|
||||
return "bdecode error";
|
||||
}
|
||||
|
||||
std::string bdecode_error_category::message(int ev) const BOOST_SYSTEM_NOEXCEPT
|
||||
{
|
||||
static char const* msgs[] =
|
||||
{
|
||||
"no error",
|
||||
"expected string in bencoded string",
|
||||
"expected colon in bencoded string",
|
||||
"unexpected end of file in bencoded string",
|
||||
"expected value (list, dict, int or string) in bencoded string",
|
||||
"bencoded nesting depth exceeded",
|
||||
"bencoded item count limit exceeded",
|
||||
};
|
||||
if (ev < 0 || ev >= int(sizeof(msgs)/sizeof(msgs[0])))
|
||||
return "Unknown error";
|
||||
return msgs[ev];
|
||||
}
|
||||
|
||||
boost::system::error_category& get_bdecode_category()
|
||||
{
|
||||
static bdecode_error_category bdecode_category;
|
||||
return bdecode_category;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue