diff --git a/include/libtorrent/lazy_entry.hpp b/include/libtorrent/lazy_entry.hpp index 1d3a694ed..1ec46fd7a 100644 --- a/include/libtorrent/lazy_entry.hpp +++ b/include/libtorrent/lazy_entry.hpp @@ -155,6 +155,7 @@ namespace libtorrent } lazy_entry* dict_append(char const* name); + void pop(); lazy_entry* dict_find(char const* name); lazy_entry const* dict_find(char const* name) const { return const_cast(this)->dict_find(name); } diff --git a/src/lazy_bdecode.cpp b/src/lazy_bdecode.cpp index a90f7fb36..c2a0a6072 100644 --- a/src/lazy_bdecode.cpp +++ b/src/lazy_bdecode.cpp @@ -51,6 +51,12 @@ namespace libtorrent #define TORRENT_FAIL_BDECODE(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; \ return -1; \ } @@ -176,7 +182,11 @@ namespace libtorrent } 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'; start = parse_int(start, end, ':', len); @@ -234,6 +244,11 @@ namespace libtorrent return &ret.val; } + void lazy_entry::pop() + { + if (m_size > 0) --m_size; + } + namespace { // the number of decimal digits needed diff --git a/test/test_primitives.cpp b/test/test_primitives.cpp index 92579c986..8cd3d97b0 100644 --- a/test/test_primitives.cpp +++ b/test/test_primitives.cpp @@ -499,6 +499,21 @@ int test_main() fprintf(stderr, "%s\n", error_string); 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 aux::session_impl* ses = new aux::session_impl(std::pair(0,0) , fingerprint("LT", 0, 0, 0, 0), "0.0.0.0", 0