improve lazy_bdecode test to cover more error cases

This commit is contained in:
Arvid Norberg 2014-05-01 03:54:47 +00:00
parent ab96600ae3
commit e19c52ec98
4 changed files with 189 additions and 4 deletions

View File

@ -425,6 +425,11 @@ namespace libtorrent
return boost::system::error_code(e, get_bdecode_category());
}
}
TORRENT_EXTRA_EXPORT char const* parse_int(char const* start
, char const* end, char delimiter, boost::int64_t& val
, bdecode_errors::error_code_enum& ec);
}
#endif

View File

@ -121,7 +121,7 @@ namespace libtorrent
std::vector<lazy_entry*> stack;
stack.push_back(&ret);
while (start < end)
while (start <= end)
{
if (stack.empty()) break; // done!

View File

@ -240,7 +240,7 @@ int natpmp::add_mapping(protocol_type p, int external_port, int local_port)
for (std::vector<mapping_t>::iterator m = m_mappings.begin()
, end(m_mappings.end()); m != end; ++m)
{
std::cout << " ADD MAPPING: " << mapping_index << " [ "
std::cout << " ADD MAPPING: " << mapping_index << " [ "
"proto: " << (i->protocol == none ? "none" : i->protocol == tcp ? "tcp" : "udp")
<< " port: " << i->external_port
<< " local-port: " << i->local_port
@ -261,7 +261,7 @@ void natpmp::try_next_mapping(int i, mutex::scoped_lock& l)
for (std::vector<mapping_t>::iterator m = m_mappings.begin()
, end(m_mappings.end()); m != end; ++m)
{
std::cout << " " << (m - m_mappings.begin()) << " [ "
std::cout << " " << (m - m_mappings.begin()) << " [ "
"proto: " << (m->protocol == none ? "none" : m->protocol == tcp ? "tcp" : "udp")
<< " port: " << m->external_port
<< " local-port: " << m->local_port

View File

@ -202,7 +202,6 @@ int test_main()
, get_bdecode_category()));
}
// test integers that don't fit in 64 bits
{
char b[] = "i18446744073709551615e";
@ -262,12 +261,193 @@ int test_main()
TEST_CHECK(ret == -1);
}
// test the depth limit
{
char b[2048];
for (int i = 0; i < 1024; ++i)
b[i]= 'l';
for (int i = 1024; i < 2048; ++i)
b[i]= 'e';
// 1024 levels nested lists
lazy_entry e;
error_code ec;
int ret = lazy_bdecode(b, b + sizeof(b), e, ec);
TEST_CHECK(ret != 0);
TEST_EQUAL(ec, error_code(bdecode_errors::depth_exceeded
, get_bdecode_category()));
}
// test the item limit
{
char b[10240];
b[0] = 'l';
int i = 1;
for (i = 1; i < 10239; i += 2)
memcpy(&b[i], "0:", 2);
b[i] = 'e';
lazy_entry e;
error_code ec;
int ret = lazy_bdecode(b, b + i + 1, e, ec, NULL, 1000, 1000);
TEST_CHECK(ret != 0);
TEST_EQUAL(ec, error_code(bdecode_errors::limit_exceeded
, get_bdecode_category()));
}
// test unexpected EOF
{
char b[] = "l2:.."; // expected terminating 'e'
lazy_entry e;
error_code ec;
int ret = lazy_bdecode(b, b + sizeof(b)-1, e, ec, NULL);
TEST_CHECK(ret != 0);
printf("%s\n", print_entry(e).c_str());
TEST_EQUAL(ec, error_code(bdecode_errors::unexpected_eof
, get_bdecode_category()));
}
// test unexpected EOF (really expected terminator)
{
char b[] = "l2:..0"; // expected terminating 'e' instead of '0'
lazy_entry e;
error_code ec;
int ret = lazy_bdecode(b, b + sizeof(b)-1, e, ec, NULL);
TEST_CHECK(ret != 0);
printf("%s\n", print_entry(e).c_str());
TEST_EQUAL(ec, error_code(bdecode_errors::unexpected_eof
, get_bdecode_category()));
}
// test expected string
{
char b[] = "di2ei0ee";
// expected string (dict keys must be strings)
lazy_entry e;
error_code ec;
int ret = lazy_bdecode(b, b + sizeof(b)-1, e, ec, NULL);
TEST_CHECK(ret != 0);
printf("%s\n", print_entry(e).c_str());
TEST_EQUAL(ec, error_code(bdecode_errors::expected_string
, get_bdecode_category()));
}
// test unexpected EOF while parsing dict key
{
char b[] = "d1000:..e";
lazy_entry e;
error_code ec;
int ret = lazy_bdecode(b, b + sizeof(b)-1, e, ec, NULL);
TEST_CHECK(ret != 0);
printf("%s\n", print_entry(e).c_str());
TEST_EQUAL(ec, error_code(bdecode_errors::unexpected_eof
, get_bdecode_category()));
}
// test unexpected EOF while parsing dict key
{
char b[] = "d1000:";
lazy_entry e;
error_code ec;
int ret = lazy_bdecode(b, b + sizeof(b)-1, e, ec, NULL);
TEST_CHECK(ret != 0);
printf("%s\n", print_entry(e).c_str());
TEST_EQUAL(ec, error_code(bdecode_errors::unexpected_eof
, get_bdecode_category()));
}
// test unexpected EOF while parsing dict key
{
char b[] = "d1000:";
lazy_entry e;
error_code ec;
int ret = lazy_bdecode(b, b + sizeof(b)-1, e, ec, NULL);
TEST_CHECK(ret != 0);
printf("%s\n", print_entry(e).c_str());
TEST_EQUAL(ec, error_code(bdecode_errors::unexpected_eof
, get_bdecode_category()));
}
// test unexpected EOF while parsing int
{
char b[] = "i";
lazy_entry e;
error_code ec;
int ret = lazy_bdecode(b, b + sizeof(b)-1, e, ec, NULL);
TEST_CHECK(ret != 0);
printf("%s\n", print_entry(e).c_str());
TEST_EQUAL(ec, error_code(bdecode_errors::unexpected_eof
, get_bdecode_category()));
}
// test unexpected EOF while parsing int
{
char b[] = "i10";
lazy_entry e;
error_code ec;
int ret = lazy_bdecode(b, b + sizeof(b)-1, e, ec, NULL);
TEST_CHECK(ret != 0);
printf("%s\n", print_entry(e).c_str());
TEST_EQUAL(ec, error_code(bdecode_errors::unexpected_eof
, get_bdecode_category()));
}
// test expected colon
{
char b[] = "d1000";
lazy_entry e;
error_code ec;
int ret = lazy_bdecode(b, b + sizeof(b)-1, e, ec, NULL);
TEST_CHECK(ret != 0);
printf("%s\n", print_entry(e).c_str());
TEST_EQUAL(ec, error_code(bdecode_errors::expected_colon
, get_bdecode_category()));
}
{
unsigned char buf[] = { 0x44 , 0x91 , 0x3a };
entry ent = bdecode(buf, buf + sizeof(buf));
TEST_CHECK(ent == entry());
}
// test parse_int
{
char b[] = "1234567890e";
boost::int64_t val = 0;
bdecode_errors::error_code_enum ec;
char const* e = parse_int(b, b + sizeof(b)-1, 'e', val, ec);
TEST_EQUAL(val, 1234567890);
TEST_EQUAL(e, b + sizeof(b) - 2);
}
{
char b[] = "9223372036854775808:";
boost::int64_t val = 0;
bdecode_errors::error_code_enum ec;
char const* e = parse_int(b, b + sizeof(b)-1, ':', val, ec);
TEST_CHECK(ec == bdecode_errors::overflow);
}
{
char b[] = "928";
boost::int64_t val = 0;
bdecode_errors::error_code_enum ec;
char const* e = parse_int(b, b + sizeof(b)-1, ':', val, ec);
TEST_CHECK(ec == bdecode_errors::expected_colon);
}
return 0;
}