make bdecoder more robust when encountering errors (leave the resulting tree consistent)
This commit is contained in:
parent
be339c244f
commit
c384d00dbf
|
@ -155,6 +155,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_entry* dict_append(char const* name);
|
lazy_entry* dict_append(char const* name);
|
||||||
|
void pop();
|
||||||
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); }
|
||||||
|
|
|
@ -51,6 +51,12 @@ namespace libtorrent
|
||||||
#define TORRENT_FAIL_BDECODE(code) \
|
#define TORRENT_FAIL_BDECODE(code) \
|
||||||
{ \
|
{ \
|
||||||
ec = code; \
|
ec = code; \
|
||||||
|
while (!stack.empty()) { \
|
||||||
|
top = stack.back(); \
|
||||||
|
fprintf(stderr, "top->type: %d\n", top->type()); \
|
||||||
|
if (top->type() == lazy_entry::dict_t || top->type() == lazy_entry::list_t) top->pop(); \
|
||||||
|
stack.pop_back(); \
|
||||||
|
} \
|
||||||
if (error_pos) *error_pos = start - orig_start; \
|
if (error_pos) *error_pos = start - orig_start; \
|
||||||
return -1; \
|
return -1; \
|
||||||
}
|
}
|
||||||
|
@ -176,7 +182,11 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
if (!is_digit(t)) TORRENT_FAIL_BDECODE(errors::expected_value);
|
if (!is_digit(t))
|
||||||
|
{
|
||||||
|
int a = 0;
|
||||||
|
TORRENT_FAIL_BDECODE(errors::expected_value);
|
||||||
|
}
|
||||||
|
|
||||||
boost::int64_t len = t - '0';
|
boost::int64_t len = t - '0';
|
||||||
start = parse_int(start, end, ':', len);
|
start = parse_int(start, end, ':', len);
|
||||||
|
@ -234,6 +244,11 @@ namespace libtorrent
|
||||||
return &ret.val;
|
return &ret.val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lazy_entry::pop()
|
||||||
|
{
|
||||||
|
if (m_size > 0) --m_size;
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// the number of decimal digits needed
|
// the number of decimal digits needed
|
||||||
|
|
|
@ -499,6 +499,21 @@ int test_main()
|
||||||
fprintf(stderr, "%s\n", error_string);
|
fprintf(stderr, "%s\n", error_string);
|
||||||
TEST_EQUAL(error_string, std::string("missing 'C2' key"));
|
TEST_EQUAL(error_string, std::string("missing 'C2' key"));
|
||||||
|
|
||||||
|
// test empty strings [ { "":1 }, "" ]
|
||||||
|
char const test_msg6[] = "ld0:i1ee0:e";
|
||||||
|
lazy_bdecode(test_msg6, test_msg6 + sizeof(test_msg6)-1, ent, ec);
|
||||||
|
fprintf(stderr, "%s\n", print_entry(ent).c_str());
|
||||||
|
TEST_CHECK(ent.type() == lazy_entry::list_t);
|
||||||
|
if (ent.type() == lazy_entry::list_t)
|
||||||
|
{
|
||||||
|
TEST_CHECK(ent.list_size() == 2);
|
||||||
|
if (ent.list_size() == 2)
|
||||||
|
{
|
||||||
|
TEST_CHECK(ent.list_at(0)->dict_find_int_value("") == 1);
|
||||||
|
TEST_CHECK(ent.list_at(1)->string_value() == "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// test external ip voting
|
// test external ip voting
|
||||||
aux::session_impl* ses = new aux::session_impl(std::pair<int, int>(0,0)
|
aux::session_impl* ses = new aux::session_impl(std::pair<int, int>(0,0)
|
||||||
, fingerprint("LT", 0, 0, 0, 0), "0.0.0.0", 0
|
, fingerprint("LT", 0, 0, 0, 0), "0.0.0.0", 0
|
||||||
|
|
Loading…
Reference in New Issue