diff --git a/include/libtorrent/bencode.hpp b/include/libtorrent/bencode.hpp index 057e3d644..becf4d528 100755 --- a/include/libtorrent/bencode.hpp +++ b/include/libtorrent/bencode.hpp @@ -234,6 +234,9 @@ namespace libtorrent if (in == end) { err = true; +#ifndef NDEBUG + ret.m_type_queried = false; +#endif return; } switch (*in) @@ -250,6 +253,9 @@ namespace libtorrent ++in; // 'e' ret = entry(entry::int_t); ret.integer() = boost::lexical_cast(val); +#ifndef NDEBUG + ret.m_type_queried = false; +#endif } break; // ---------------------------------------------- @@ -263,13 +269,25 @@ namespace libtorrent ret.list().push_back(entry()); entry& e = ret.list().back(); bdecode_recursive(in, end, e, err); - if (err) return; + if (err) + { +#ifndef NDEBUG + ret.m_type_queried = false; +#endif + return; + } if (in == end) { err = true; +#ifndef NDEBUG + ret.m_type_queried = false; +#endif return; } } +#ifndef NDEBUG + ret.m_type_queried = false; +#endif TORRENT_ASSERT(*in == 'e'); ++in; // 'e' } break; @@ -284,16 +302,34 @@ namespace libtorrent { entry key; bdecode_recursive(in, end, key, err); - if (err) return; + if (err || key.type() != entry::string_t) + { +#ifndef NDEBUG + ret.m_type_queried = false; +#endif + return; + } entry& e = ret[key.string()]; bdecode_recursive(in, end, e, err); - if (err) return; + if (err) + { +#ifndef NDEBUG + ret.m_type_queried = false; +#endif + return; + } if (in == end) { err = true; +#ifndef NDEBUG + ret.m_type_queried = false; +#endif return; } } +#ifndef NDEBUG + ret.m_type_queried = false; +#endif TORRENT_ASSERT(*in == 'e'); ++in; // 'e' } break; @@ -304,19 +340,37 @@ namespace libtorrent if (isdigit((unsigned char)*in)) { std::string len_s = read_until(in, end, ':', err); - if (err) return; + if (err) + { +#ifndef NDEBUG + ret.m_type_queried = false; +#endif + return; + } TORRENT_ASSERT(*in == ':'); ++in; // ':' int len = std::atoi(len_s.c_str()); ret = entry(entry::string_t); read_string(in, end, len, ret.string(), err); - if (err) return; + if (err) + { +#ifndef NDEBUG + ret.m_type_queried = false; +#endif + return; + } } else { err = true; +#ifndef NDEBUG + ret.m_type_queried = false; +#endif return; } +#ifndef NDEBUG + ret.m_type_queried = false; +#endif } } } @@ -333,6 +387,7 @@ namespace libtorrent entry e; bool err = false; detail::bdecode_recursive(start, end, e, err); + TORRENT_ASSERT(e.m_type_queried == false); if (err) { #ifdef BOOST_NO_EXCEPTIONS diff --git a/include/libtorrent/entry.hpp b/include/libtorrent/entry.hpp index 1c25cc7c7..ffad224e5 100755 --- a/include/libtorrent/entry.hpp +++ b/include/libtorrent/entry.hpp @@ -170,6 +170,15 @@ namespace libtorrent void print(std::ostream& os, int indent = 0) const; +#ifndef NDEBUG + // in debug mode this is set to false by bdecode + // to indicate that the program has not yet queried + // the type of this entry, and sould not assume + // that it has a certain type. This is asserted in + // the accessor functions. This does not apply if + // exceptions are used. + mutable bool m_type_queried; +#endif private: void construct(data_type t); @@ -210,9 +219,20 @@ namespace libtorrent return os; } - inline entry::data_type entry::type() const { return m_type; } + inline entry::data_type entry::type() const + { +#ifndef NDEBUG + m_type_queried = true; +#endif + return m_type; + } - inline entry::entry(): m_type(undefined_t) {} + inline entry::entry(): m_type(undefined_t) + { +#ifndef NDEBUG + m_type_queried = true; +#endif + } inline entry::entry(data_type t): m_type(t) { construct(t); } inline entry::entry(const entry& e) { copy(e); } inline entry::~entry() { destruct(); } @@ -229,6 +249,8 @@ namespace libtorrent if (m_type == undefined_t) construct(int_t); #ifndef BOOST_NO_EXCEPTIONS if (m_type != int_t) throw type_error("invalid type requested from entry"); +#elif !defined NDEBUG + TORRENT_ASSERT(m_type_queried); #endif TORRENT_ASSERT(m_type == int_t); return *reinterpret_cast(data); @@ -238,6 +260,8 @@ namespace libtorrent { #ifndef BOOST_NO_EXCEPTIONS if (m_type != int_t) throw type_error("invalid type requested from entry"); +#elif !defined NDEBUG + TORRENT_ASSERT(m_type_queried); #endif TORRENT_ASSERT(m_type == int_t); return *reinterpret_cast(data); @@ -248,6 +272,8 @@ namespace libtorrent if (m_type == undefined_t) construct(string_t); #ifndef BOOST_NO_EXCEPTIONS if (m_type != string_t) throw type_error("invalid type requested from entry"); +#elif !defined NDEBUG + TORRENT_ASSERT(m_type_queried); #endif TORRENT_ASSERT(m_type == string_t); return *reinterpret_cast(data); @@ -257,6 +283,8 @@ namespace libtorrent { #ifndef BOOST_NO_EXCEPTIONS if (m_type != string_t) throw type_error("invalid type requested from entry"); +#elif !defined NDEBUG + TORRENT_ASSERT(m_type_queried); #endif TORRENT_ASSERT(m_type == string_t); return *reinterpret_cast(data); @@ -267,6 +295,8 @@ namespace libtorrent if (m_type == undefined_t) construct(list_t); #ifndef BOOST_NO_EXCEPTIONS if (m_type != list_t) throw type_error("invalid type requested from entry"); +#elif !defined NDEBUG + TORRENT_ASSERT(m_type_queried); #endif TORRENT_ASSERT(m_type == list_t); return *reinterpret_cast(data); @@ -276,6 +306,8 @@ namespace libtorrent { #ifndef BOOST_NO_EXCEPTIONS if (m_type != list_t) throw type_error("invalid type requested from entry"); +#elif !defined NDEBUG + TORRENT_ASSERT(m_type_queried); #endif TORRENT_ASSERT(m_type == list_t); return *reinterpret_cast(data); @@ -286,6 +318,8 @@ namespace libtorrent if (m_type == undefined_t) construct(dictionary_t); #ifndef BOOST_NO_EXCEPTIONS if (m_type != dictionary_t) throw type_error("invalid type requested from entry"); +#elif !defined NDEBUG + TORRENT_ASSERT(m_type_queried); #endif TORRENT_ASSERT(m_type == dictionary_t); return *reinterpret_cast(data); @@ -295,6 +329,8 @@ namespace libtorrent { #ifndef BOOST_NO_EXCEPTIONS if (m_type != dictionary_t) throw type_error("invalid type requested from entry"); +#elif !defined NDEBUG + TORRENT_ASSERT(m_type_queried); #endif TORRENT_ASSERT(m_type == dictionary_t); return *reinterpret_cast(data); diff --git a/src/entry.cpp b/src/entry.cpp index 8219ecc06..a1021930d 100755 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -144,24 +144,36 @@ namespace libtorrent entry::entry(dictionary_type const& v) { +#ifndef NDEBUG + m_type_queried = true; +#endif new(data) dictionary_type(v); m_type = dictionary_t; } entry::entry(string_type const& v) { +#ifndef NDEBUG + m_type_queried = true; +#endif new(data) string_type(v); m_type = string_t; } entry::entry(list_type const& v) { +#ifndef NDEBUG + m_type_queried = true; +#endif new(data) list_type(v); m_type = list_t; } entry::entry(integer_type const& v) { +#ifndef NDEBUG + m_type_queried = true; +#endif new(data) integer_type(v); m_type = int_t; } @@ -171,6 +183,9 @@ namespace libtorrent destruct(); new(data) dictionary_type(v); m_type = dictionary_t; +#ifndef NDEBUG + m_type_queried = true; +#endif } void entry::operator=(string_type const& v) @@ -178,6 +193,9 @@ namespace libtorrent destruct(); new(data) string_type(v); m_type = string_t; +#ifndef NDEBUG + m_type_queried = true; +#endif } void entry::operator=(list_type const& v) @@ -185,6 +203,9 @@ namespace libtorrent destruct(); new(data) list_type(v); m_type = list_t; +#ifndef NDEBUG + m_type_queried = true; +#endif } void entry::operator=(integer_type const& v) @@ -192,6 +213,9 @@ namespace libtorrent destruct(); new(data) integer_type(v); m_type = int_t; +#ifndef NDEBUG + m_type_queried = true; +#endif } bool entry::operator==(entry const& e) const @@ -235,11 +259,14 @@ namespace libtorrent TORRENT_ASSERT(m_type == undefined_t); m_type = undefined_t; } +#ifndef NDEBUG + m_type_queried = true; +#endif } void entry::copy(entry const& e) { - m_type = e.m_type; + m_type = e.type(); switch(m_type) { case int_t: @@ -257,6 +284,9 @@ namespace libtorrent default: m_type = undefined_t; } +#ifndef NDEBUG + m_type_queried = true; +#endif } void entry::destruct() @@ -279,6 +309,9 @@ namespace libtorrent TORRENT_ASSERT(m_type == undefined_t); break; } +#ifndef NDEBUG + m_type_queried = false; +#endif } void entry::swap(entry& e)