void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err, int depth) { if (depth >= 100) { err = true; return; } if (in == end) { err = true; #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } switch (*in) { // ---------------------------------------------- // integer case 'i': { ++in; // 'i' std::string val = read_until(in, end, 'e', err); if (err) return; TORRENT_ASSERT(*in == 'e'); ++in; // 'e' ret = entry(entry::int_t); char* end_pointer; ret.integer() = strtoll(val.c_str(), &end_pointer, 10); #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif if (end_pointer == val.c_str()) { err = true; return; } } break; // ---------------------------------------------- // list case 'l': { ret = entry(entry::list_t); ++in; // 'l' while (*in != 'e') { ret.list().push_back(entry()); entry& e = ret.list().back(); bdecode_recursive(in, end, e, err, depth + 1); if (err) { #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } if (in == end) { err = true; #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } } #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif TORRENT_ASSERT(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // dictionary case 'd': { ret = entry(entry::dictionary_t); ++in; // 'd' while (*in != 'e') { entry key; bdecode_recursive(in, end, key, err, depth + 1); if (err || key.type() != entry::string_t) { #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } entry& e = ret[key.string()]; bdecode_recursive(in, end, e, err, depth + 1); if (err) { #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } if (in == end) { err = true; #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } } #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif TORRENT_ASSERT(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // string default: if (is_digit(boost::uint8_t(*in))) { std::string len_s = read_until(in, end, ':', err); if (err) { #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } TORRENT_ASSERT(*in == ':'); ++in; // ':' int len = atoi(len_s.c_str()); ret = entry(entry::string_t); read_string(in, end, len, ret.string(), err); if (err) { #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } } else { err = true; #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif return; } #ifdef TORRENT_DEBUG ret.m_type_queried = false; #endif } }
void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err, int depth) { if (depth >= 100) { err = true; return; } if (in == end) { err = true; return; } switch (*in) { // ---------------------------------------------- // integer case 'i': { ++in; // 'i' std::string val = read_until(in, end, 'e', err); if (err) return; BOOST_ASSERT(*in == 'e'); ++in; // 'e' ret = entry(entry::int_t); char* end_pointer; #if defined WIN32 && !defined _MINGW ret.integer() = _strtoi64(val.c_str(), &end_pointer, 10); #else ret.integer() = strtoll(val.c_str(), &end_pointer, 10); #endif if (end_pointer == val.c_str()) { err = true; return; } } break; // ---------------------------------------------- // list case 'l': { ret = entry(entry::list_t); ++in; // 'l' while (*in != 'e') { ret.list().push_back(entry()); entry& e = ret.list().back(); bdecode_recursive(in, end, e, err, depth + 1); if (err) { return; } if (in == end) { err = true; return; } } BOOST_ASSERT(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // dictionary case 'd': { ret = entry(entry::dictionary_t); ++in; // 'd' while (*in != 'e') { entry key; bdecode_recursive(in, end, key, err, depth + 1); if (err || key.type() != entry::string_t) { return; } entry& e = ret[key.string()]; bdecode_recursive(in, end, e, err, depth + 1); if (err) { return; } if (in == end) { err = true; return; } } BOOST_ASSERT(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // string default: if (is_digit((unsigned char)*in)) { std::string len_s = read_until(in, end, ':', err); if (err) { return; } BOOST_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; } } else { err = true; return; } } }
void bdecode_recursive(InIt& in, InIt end, entry& ret) { if (in == end) throw invalid_encoding(); switch (*in) { // ---------------------------------------------- // integer case 'i': { ++in; // 'i' std::string val = read_until(in, end, 'e'); assert(*in == 'e'); ++in; // 'e' ret = entry(entry::int_t); ret.integer() = boost::lexical_cast<entry::integer_type>(val); } break; // ---------------------------------------------- // list case 'l': { ret = entry(entry::list_t); ++in; // 'l' while (*in != 'e') { ret.list().push_back(entry()); entry& e = ret.list().back(); bdecode_recursive(in, end, e); if (in == end) throw invalid_encoding(); } assert(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // dictionary case 'd': { ret = entry(entry::dictionary_t); ++in; // 'd' while (*in != 'e') { entry key; bdecode_recursive(in, end, key); entry& e = ret[key.string()]; bdecode_recursive(in, end, e); if (in == end) throw invalid_encoding(); } assert(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // string default: if (isdigit(*in)) { std::string len_s = read_until(in, end, ':'); assert(*in == ':'); ++in; // ':' int len = std::atoi(len_s.c_str()); ret = entry(entry::string_t); ret.string() = read_string(in, end, len); } else { throw invalid_encoding(); } } }
void bdecode_recursive(InIt& in, InIt end, entry& ret, bool& err, int depth) { if (depth >= 100) { err = true; return; } if (in == end) { err = true; return; } switch (*in) { // ---------------------------------------------- // integer case 'i': { ++in; // 'i' std::string val = read_until(in, end, 'e', err); if (err) return; TORRENT_ASSERT(*in == 'e'); ++in; // 'e' ret = entry(entry::int_t); ret.integer() = boost::lexical_cast<entry::integer_type>(val); } break; // ---------------------------------------------- // list case 'l': { ret = entry(entry::list_t); ++in; // 'l' while (*in != 'e') { ret.list().push_back(entry()); entry& e = ret.list().back(); bdecode_recursive(in, end, e, err, depth + 1); if (err) return; if (in == end) { err = true; return; } } TORRENT_ASSERT(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // dictionary case 'd': { ret = entry(entry::dictionary_t); ++in; // 'd' while (*in != 'e') { entry key; bdecode_recursive(in, end, key, err, depth + 1); if (err) return; entry& e = ret[key.string()]; bdecode_recursive(in, end, e, err, depth + 1); if (err) return; if (in == end) { err = true; return; } } TORRENT_ASSERT(*in == 'e'); ++in; // 'e' } break; // ---------------------------------------------- // string default: if (isdigit((unsigned char)*in)) { 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(), err); if (err) return; } else { err = true; return; } } }