From 54bf83739d35dd6dc9346e7c1e00e7d650b8c7ab Mon Sep 17 00:00:00 2001 From: arvidn Date: Fri, 11 Dec 2015 18:27:28 -0500 Subject: [PATCH] fix assert in bdecode assert for strings with prefixes of 6 or more digits --- include/libtorrent/bdecode.hpp | 3 ++- test/test_bdecode.cpp | 29 +++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/include/libtorrent/bdecode.hpp b/include/libtorrent/bdecode.hpp index 791479cd6..d8e10adc7 100644 --- a/include/libtorrent/bdecode.hpp +++ b/include/libtorrent/bdecode.hpp @@ -187,7 +187,8 @@ struct bdecode_token TORRENT_ASSERT(type != string || header_size >= 2); TORRENT_ASSERT(off <= max_offset); TORRENT_ASSERT(next <= max_next_item); - TORRENT_ASSERT(header_size < 8); + // the string has 2 implied header bytes, to allow for longer prefixes + TORRENT_ASSERT(header_size < 8 || (type == string && header_size < 10)); TORRENT_ASSERT(t >= 0 && t <= end); } diff --git a/test/test_bdecode.cpp b/test/test_bdecode.cpp index 6652370de..fd5f0a5fc 100644 --- a/test/test_bdecode.cpp +++ b/test/test_bdecode.cpp @@ -62,10 +62,31 @@ TORRENT_TEST(string) printf("%s\n", print_entry(e).c_str()); std::pair section = e.data_section(); TEST_CHECK(std::memcmp(b, section.first, section.second) == 0); - TEST_CHECK(section.second == sizeof(b) - 1); - TEST_CHECK(e.type() == bdecode_node::string_t); - TEST_CHECK(e.string_value() == std::string("abcdefghijklmnopqrstuvwxyz")); - TEST_CHECK(e.string_length() == 26); + TEST_EQUAL(section.second, sizeof(b) - 1); + TEST_EQUAL(e.type(), bdecode_node::string_t); + TEST_EQUAL(e.string_value(), std::string("abcdefghijklmnopqrstuvwxyz")); + TEST_EQUAL(e.string_length(), 26); +} + +// test string-prefix +TORRENT_TEST(string_prefix1) +{ + // test edge-case of a string that's nearly too long + std::string test; + test.resize(1000000 + 8); + memcpy(&test[0], "1000000:", 8); + // test is a valid bencoded string, that's quite long + bdecode_node e; + error_code ec; + int ret = bdecode(test.c_str(), test.c_str() + test.size(), e, ec); + TEST_CHECK(ret == 0); + printf("%d bytes string\n", e.string_length()); + std::pair section = e.data_section(); + TEST_CHECK(std::memcmp(test.c_str(), section.first, section.second) == 0); + TEST_EQUAL(section.second, int(test.size())); + TEST_EQUAL(e.type(), bdecode_node::string_t); + TEST_EQUAL(e.string_length(), 1000000); + TEST_EQUAL(e.string_ptr(), test.c_str() + 8); } // test list