diff --git a/libtorrent/include/libtorrent/bencode.hpp b/libtorrent/include/libtorrent/bencode.hpp index 66da191ab..1d3f1ea2b 100755 --- a/libtorrent/include/libtorrent/bencode.hpp +++ b/libtorrent/include/libtorrent/bencode.hpp @@ -135,26 +135,38 @@ namespace libtorrent } template - std::string read_until(InIt& in, InIt end, char end_token) + std::string read_until(InIt& in, InIt end, char end_token, bool& err) { - if (in == end) throw invalid_encoding(); std::string ret; + if (in == end) + { + err = true; + return ret; + } while (*in != end_token) { ret += *in; ++in; - if (in == end) throw invalid_encoding(); + if (in == end) + { + err = true; + return ret; + } } return ret; } template - void read_string(InIt& in, InIt end, int len, std::string& str) + void read_string(InIt& in, InIt end, int len, std::string& str, bool& err) { TORRENT_ASSERT(len >= 0); for (int i = 0; i < len; ++i) { - if (in == end) throw invalid_encoding(); + if (in == end) + { + err = true; + return; + } str += *in; ++in; } @@ -202,9 +214,13 @@ namespace libtorrent } template - void bdecode_recursive(InIt& in, InIt end, entry& ret) + void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err) { - if (in == end) throw invalid_encoding(); + if (in == end) + { + err = true; + return; + } switch (*in) { @@ -213,7 +229,8 @@ namespace libtorrent case 'i': { ++in; // 'i' - std::string val = read_until(in, end, 'e'); + std::string val = read_until(in, end, 'e', err); + if (err) return; TORRENT_ASSERT(*in == 'e'); ++in; // 'e' ret = entry(entry::int_t); @@ -230,8 +247,13 @@ namespace libtorrent { ret.list().push_back(entry()); entry& e = ret.list().back(); - bdecode_recursive(in, end, e); - if (in == end) throw invalid_encoding(); + bdecode_recursive(in, end, e, err); + if (err) return; + if (in == end) + { + err = true; + return; + } } TORRENT_ASSERT(*in == 'e'); ++in; // 'e' @@ -246,10 +268,16 @@ namespace libtorrent while (*in != 'e') { entry key; - bdecode_recursive(in, end, key); + bdecode_recursive(in, end, key, err); + if (err) return; entry& e = ret[key.string()]; - bdecode_recursive(in, end, e); - if (in == end) throw invalid_encoding(); + bdecode_recursive(in, end, e, err); + if (err) return; + if (in == end) + { + err = true; + return; + } } TORRENT_ASSERT(*in == 'e'); ++in; // 'e' @@ -260,16 +288,19 @@ namespace libtorrent default: if (isdigit((unsigned char)*in)) { - std::string len_s = read_until(in, end, ':'); + std::string len_s = read_until(in, end, ':', err); + if (err) 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()); + read_string(in, end, len, ret.string(), err); + if (err) return; } else { - throw invalid_encoding(); + err = true; + return; } } } @@ -284,16 +315,18 @@ namespace libtorrent template entry bdecode(InIt start, InIt end) { - try - { - entry e; - detail::bdecode_recursive(start, end, e); - return e; - } - catch(type_error&) + entry e; + bool err = false; + detail::bdecode_recursive(start, end, e, err); + if (err) { +#ifdef BOOST_NO_EXCEPTIONS + return entry(); +#else throw invalid_encoding(); +#endif } + return e; } } diff --git a/libtorrent/include/libtorrent/entry.hpp b/libtorrent/include/libtorrent/entry.hpp index 7fd6c8c53..1c25cc7c7 100755 --- a/libtorrent/include/libtorrent/entry.hpp +++ b/libtorrent/include/libtorrent/entry.hpp @@ -161,8 +161,10 @@ namespace libtorrent // is a dictionary, otherwise they will throw entry& operator[](char const* key); entry& operator[](std::string const& key); +#ifndef BOOST_NO_EXCEPTIONS const entry& operator[](char const* key) const; const entry& operator[](std::string const& key) const; +#endif entry* find_key(char const* key); entry const* find_key(char const* key) const; @@ -221,55 +223,80 @@ namespace libtorrent copy(e); } + inline entry::integer_type& entry::integer() { 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"); +#endif + TORRENT_ASSERT(m_type == int_t); return *reinterpret_cast(data); } inline entry::integer_type const& entry::integer() const { +#ifndef BOOST_NO_EXCEPTIONS if (m_type != int_t) throw type_error("invalid type requested from entry"); +#endif + TORRENT_ASSERT(m_type == int_t); return *reinterpret_cast(data); } inline entry::string_type& entry::string() { 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"); +#endif + TORRENT_ASSERT(m_type == string_t); return *reinterpret_cast(data); } inline entry::string_type const& entry::string() const { +#ifndef BOOST_NO_EXCEPTIONS if (m_type != string_t) throw type_error("invalid type requested from entry"); +#endif + TORRENT_ASSERT(m_type == string_t); return *reinterpret_cast(data); } inline entry::list_type& entry::list() { 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"); +#endif + TORRENT_ASSERT(m_type == list_t); return *reinterpret_cast(data); } inline entry::list_type const& entry::list() const { +#ifndef BOOST_NO_EXCEPTIONS if (m_type != list_t) throw type_error("invalid type requested from entry"); +#endif + TORRENT_ASSERT(m_type == list_t); return *reinterpret_cast(data); } inline entry::dictionary_type& entry::dict() { 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"); +#endif + TORRENT_ASSERT(m_type == dictionary_t); return *reinterpret_cast(data); } inline entry::dictionary_type const& entry::dict() const { +#ifndef BOOST_NO_EXCEPTIONS if (m_type != dictionary_t) throw type_error("invalid type requested from entry"); +#endif + TORRENT_ASSERT(m_type == dictionary_t); return *reinterpret_cast(data); } diff --git a/libtorrent/src/entry.cpp b/libtorrent/src/entry.cpp index 50c6967cc..88800713c 100755 --- a/libtorrent/src/entry.cpp +++ b/libtorrent/src/entry.cpp @@ -126,6 +126,7 @@ namespace libtorrent return &i->second; } +#ifndef BOOST_NO_EXCEPTIONS const entry& entry::operator[](char const* key) const { dictionary_type::const_iterator i = dict().find(key); @@ -138,6 +139,7 @@ namespace libtorrent { return (*this)[key.c_str()]; } +#endif entry::entry(dictionary_type const& v) {