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)
{
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<entry::integer_type>(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

View File

@ -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<integer_type*>(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<const integer_type*>(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<string_type*>(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<const string_type*>(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<list_type*>(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<const list_type*>(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<dictionary_type*>(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<const dictionary_type*>(data);

View File

@ -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)