added asserts that the type of a bencoded entry is not assumed when built with no exceptions

This commit is contained in:
Arvid Norberg 2007-12-28 19:07:28 +00:00
parent cfe5c8962e
commit e6e5b43219
3 changed files with 132 additions and 8 deletions

View File

@ -234,6 +234,9 @@ namespace libtorrent
if (in == end) if (in == end)
{ {
err = true; err = true;
#ifndef NDEBUG
ret.m_type_queried = false;
#endif
return; return;
} }
switch (*in) switch (*in)
@ -250,6 +253,9 @@ namespace libtorrent
++in; // 'e' ++in; // 'e'
ret = entry(entry::int_t); ret = entry(entry::int_t);
ret.integer() = boost::lexical_cast<entry::integer_type>(val); ret.integer() = boost::lexical_cast<entry::integer_type>(val);
#ifndef NDEBUG
ret.m_type_queried = false;
#endif
} break; } break;
// ---------------------------------------------- // ----------------------------------------------
@ -263,13 +269,25 @@ namespace libtorrent
ret.list().push_back(entry()); ret.list().push_back(entry());
entry& e = ret.list().back(); entry& e = ret.list().back();
bdecode_recursive(in, end, e, err); bdecode_recursive(in, end, e, err);
if (err) return; if (err)
{
#ifndef NDEBUG
ret.m_type_queried = false;
#endif
return;
}
if (in == end) if (in == end)
{ {
err = true; err = true;
#ifndef NDEBUG
ret.m_type_queried = false;
#endif
return; return;
} }
} }
#ifndef NDEBUG
ret.m_type_queried = false;
#endif
TORRENT_ASSERT(*in == 'e'); TORRENT_ASSERT(*in == 'e');
++in; // 'e' ++in; // 'e'
} break; } break;
@ -284,16 +302,34 @@ namespace libtorrent
{ {
entry key; entry key;
bdecode_recursive(in, end, key, err); 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()]; entry& e = ret[key.string()];
bdecode_recursive(in, end, e, err); bdecode_recursive(in, end, e, err);
if (err) return; if (err)
{
#ifndef NDEBUG
ret.m_type_queried = false;
#endif
return;
}
if (in == end) if (in == end)
{ {
err = true; err = true;
#ifndef NDEBUG
ret.m_type_queried = false;
#endif
return; return;
} }
} }
#ifndef NDEBUG
ret.m_type_queried = false;
#endif
TORRENT_ASSERT(*in == 'e'); TORRENT_ASSERT(*in == 'e');
++in; // 'e' ++in; // 'e'
} break; } break;
@ -304,19 +340,37 @@ namespace libtorrent
if (isdigit((unsigned char)*in)) if (isdigit((unsigned char)*in))
{ {
std::string len_s = read_until(in, end, ':', err); 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 == ':'); TORRENT_ASSERT(*in == ':');
++in; // ':' ++in; // ':'
int len = std::atoi(len_s.c_str()); int len = std::atoi(len_s.c_str());
ret = entry(entry::string_t); ret = entry(entry::string_t);
read_string(in, end, len, ret.string(), err); read_string(in, end, len, ret.string(), err);
if (err) return; if (err)
{
#ifndef NDEBUG
ret.m_type_queried = false;
#endif
return;
}
} }
else else
{ {
err = true; err = true;
#ifndef NDEBUG
ret.m_type_queried = false;
#endif
return; return;
} }
#ifndef NDEBUG
ret.m_type_queried = false;
#endif
} }
} }
} }
@ -333,6 +387,7 @@ namespace libtorrent
entry e; entry e;
bool err = false; bool err = false;
detail::bdecode_recursive(start, end, e, err); detail::bdecode_recursive(start, end, e, err);
TORRENT_ASSERT(e.m_type_queried == false);
if (err) if (err)
{ {
#ifdef BOOST_NO_EXCEPTIONS #ifdef BOOST_NO_EXCEPTIONS

View File

@ -170,6 +170,15 @@ namespace libtorrent
void print(std::ostream& os, int indent = 0) const; 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: private:
void construct(data_type t); void construct(data_type t);
@ -210,9 +219,20 @@ namespace libtorrent
return os; 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(data_type t): m_type(t) { construct(t); }
inline entry::entry(const entry& e) { copy(e); } inline entry::entry(const entry& e) { copy(e); }
inline entry::~entry() { destruct(); } inline entry::~entry() { destruct(); }
@ -229,6 +249,8 @@ namespace libtorrent
if (m_type == undefined_t) construct(int_t); if (m_type == undefined_t) construct(int_t);
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
if (m_type != int_t) throw type_error("invalid type requested from entry"); if (m_type != int_t) throw type_error("invalid type requested from entry");
#elif !defined NDEBUG
TORRENT_ASSERT(m_type_queried);
#endif #endif
TORRENT_ASSERT(m_type == int_t); TORRENT_ASSERT(m_type == int_t);
return *reinterpret_cast<integer_type*>(data); return *reinterpret_cast<integer_type*>(data);
@ -238,6 +260,8 @@ namespace libtorrent
{ {
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
if (m_type != int_t) throw type_error("invalid type requested from entry"); if (m_type != int_t) throw type_error("invalid type requested from entry");
#elif !defined NDEBUG
TORRENT_ASSERT(m_type_queried);
#endif #endif
TORRENT_ASSERT(m_type == int_t); TORRENT_ASSERT(m_type == int_t);
return *reinterpret_cast<const integer_type*>(data); return *reinterpret_cast<const integer_type*>(data);
@ -248,6 +272,8 @@ namespace libtorrent
if (m_type == undefined_t) construct(string_t); if (m_type == undefined_t) construct(string_t);
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
if (m_type != string_t) throw type_error("invalid type requested from entry"); if (m_type != string_t) throw type_error("invalid type requested from entry");
#elif !defined NDEBUG
TORRENT_ASSERT(m_type_queried);
#endif #endif
TORRENT_ASSERT(m_type == string_t); TORRENT_ASSERT(m_type == string_t);
return *reinterpret_cast<string_type*>(data); return *reinterpret_cast<string_type*>(data);
@ -257,6 +283,8 @@ namespace libtorrent
{ {
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
if (m_type != string_t) throw type_error("invalid type requested from entry"); if (m_type != string_t) throw type_error("invalid type requested from entry");
#elif !defined NDEBUG
TORRENT_ASSERT(m_type_queried);
#endif #endif
TORRENT_ASSERT(m_type == string_t); TORRENT_ASSERT(m_type == string_t);
return *reinterpret_cast<const string_type*>(data); return *reinterpret_cast<const string_type*>(data);
@ -267,6 +295,8 @@ namespace libtorrent
if (m_type == undefined_t) construct(list_t); if (m_type == undefined_t) construct(list_t);
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
if (m_type != list_t) throw type_error("invalid type requested from entry"); if (m_type != list_t) throw type_error("invalid type requested from entry");
#elif !defined NDEBUG
TORRENT_ASSERT(m_type_queried);
#endif #endif
TORRENT_ASSERT(m_type == list_t); TORRENT_ASSERT(m_type == list_t);
return *reinterpret_cast<list_type*>(data); return *reinterpret_cast<list_type*>(data);
@ -276,6 +306,8 @@ namespace libtorrent
{ {
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
if (m_type != list_t) throw type_error("invalid type requested from entry"); if (m_type != list_t) throw type_error("invalid type requested from entry");
#elif !defined NDEBUG
TORRENT_ASSERT(m_type_queried);
#endif #endif
TORRENT_ASSERT(m_type == list_t); TORRENT_ASSERT(m_type == list_t);
return *reinterpret_cast<const list_type*>(data); return *reinterpret_cast<const list_type*>(data);
@ -286,6 +318,8 @@ namespace libtorrent
if (m_type == undefined_t) construct(dictionary_t); if (m_type == undefined_t) construct(dictionary_t);
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
if (m_type != dictionary_t) throw type_error("invalid type requested from entry"); if (m_type != dictionary_t) throw type_error("invalid type requested from entry");
#elif !defined NDEBUG
TORRENT_ASSERT(m_type_queried);
#endif #endif
TORRENT_ASSERT(m_type == dictionary_t); TORRENT_ASSERT(m_type == dictionary_t);
return *reinterpret_cast<dictionary_type*>(data); return *reinterpret_cast<dictionary_type*>(data);
@ -295,6 +329,8 @@ namespace libtorrent
{ {
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
if (m_type != dictionary_t) throw type_error("invalid type requested from entry"); if (m_type != dictionary_t) throw type_error("invalid type requested from entry");
#elif !defined NDEBUG
TORRENT_ASSERT(m_type_queried);
#endif #endif
TORRENT_ASSERT(m_type == dictionary_t); TORRENT_ASSERT(m_type == dictionary_t);
return *reinterpret_cast<const dictionary_type*>(data); return *reinterpret_cast<const dictionary_type*>(data);

View File

@ -144,24 +144,36 @@ namespace libtorrent
entry::entry(dictionary_type const& v) entry::entry(dictionary_type const& v)
{ {
#ifndef NDEBUG
m_type_queried = true;
#endif
new(data) dictionary_type(v); new(data) dictionary_type(v);
m_type = dictionary_t; m_type = dictionary_t;
} }
entry::entry(string_type const& v) entry::entry(string_type const& v)
{ {
#ifndef NDEBUG
m_type_queried = true;
#endif
new(data) string_type(v); new(data) string_type(v);
m_type = string_t; m_type = string_t;
} }
entry::entry(list_type const& v) entry::entry(list_type const& v)
{ {
#ifndef NDEBUG
m_type_queried = true;
#endif
new(data) list_type(v); new(data) list_type(v);
m_type = list_t; m_type = list_t;
} }
entry::entry(integer_type const& v) entry::entry(integer_type const& v)
{ {
#ifndef NDEBUG
m_type_queried = true;
#endif
new(data) integer_type(v); new(data) integer_type(v);
m_type = int_t; m_type = int_t;
} }
@ -171,6 +183,9 @@ namespace libtorrent
destruct(); destruct();
new(data) dictionary_type(v); new(data) dictionary_type(v);
m_type = dictionary_t; m_type = dictionary_t;
#ifndef NDEBUG
m_type_queried = true;
#endif
} }
void entry::operator=(string_type const& v) void entry::operator=(string_type const& v)
@ -178,6 +193,9 @@ namespace libtorrent
destruct(); destruct();
new(data) string_type(v); new(data) string_type(v);
m_type = string_t; m_type = string_t;
#ifndef NDEBUG
m_type_queried = true;
#endif
} }
void entry::operator=(list_type const& v) void entry::operator=(list_type const& v)
@ -185,6 +203,9 @@ namespace libtorrent
destruct(); destruct();
new(data) list_type(v); new(data) list_type(v);
m_type = list_t; m_type = list_t;
#ifndef NDEBUG
m_type_queried = true;
#endif
} }
void entry::operator=(integer_type const& v) void entry::operator=(integer_type const& v)
@ -192,6 +213,9 @@ namespace libtorrent
destruct(); destruct();
new(data) integer_type(v); new(data) integer_type(v);
m_type = int_t; m_type = int_t;
#ifndef NDEBUG
m_type_queried = true;
#endif
} }
bool entry::operator==(entry const& e) const bool entry::operator==(entry const& e) const
@ -235,11 +259,14 @@ namespace libtorrent
TORRENT_ASSERT(m_type == undefined_t); TORRENT_ASSERT(m_type == undefined_t);
m_type = undefined_t; m_type = undefined_t;
} }
#ifndef NDEBUG
m_type_queried = true;
#endif
} }
void entry::copy(entry const& e) void entry::copy(entry const& e)
{ {
m_type = e.m_type; m_type = e.type();
switch(m_type) switch(m_type)
{ {
case int_t: case int_t:
@ -257,6 +284,9 @@ namespace libtorrent
default: default:
m_type = undefined_t; m_type = undefined_t;
} }
#ifndef NDEBUG
m_type_queried = true;
#endif
} }
void entry::destruct() void entry::destruct()
@ -279,6 +309,9 @@ namespace libtorrent
TORRENT_ASSERT(m_type == undefined_t); TORRENT_ASSERT(m_type == undefined_t);
break; break;
} }
#ifndef NDEBUG
m_type_queried = false;
#endif
} }
void entry::swap(entry& e) void entry::swap(entry& e)