# Limit the unordered bencode dictionary check to the info dictionary and all its elements. Index: libtorrent/src/torrent/object.h =================================================================== --- libtorrent/src/torrent/object.h (revision 1093) +++ libtorrent/src/torrent/object.h (working copy) @@ -75,6 +75,8 @@ static const uint32_t mask_internal = 0xffff; static const uint32_t mask_public = ~mask_internal; + static const uint32_t flag_unordered = 0x100; // bencode dictionary was not sorted + enum type_type { TYPE_NONE, TYPE_VALUE, @@ -109,6 +111,9 @@ void set_flags(uint32_t f) { m_flags |= f & mask_public; } void unset_flags(uint32_t f) { m_flags &= ~(f & mask_public); } + void set_internal_flags(uint32_t f) { m_flags |= f & (mask_internal & ~mask_type); } + void unset_internal_flags(uint32_t f) { m_flags &= ~(f & (mask_internal & ~mask_type)); } + // Add functions for setting/clearing the public flags. bool is_value() const { return type() == TYPE_VALUE; } Index: libtorrent/src/torrent/object_stream.cc =================================================================== --- libtorrent/src/torrent/object_stream.cc (revision 1093) +++ libtorrent/src/torrent/object_stream.cc (working copy) @@ -96,6 +96,9 @@ Object::list_iterator itr = object->as_list().insert(object->as_list().end(), Object()); object_read_bencode(input, &*itr, depth); + + if (itr->flags() & Object::flag_unordered) + object->set_internal_flags(Object::flag_unordered); } break; @@ -107,7 +110,7 @@ if (++depth >= 1024) break; - // Object::string_type last; + Object::string_type last; while (input->good()) { if (input->peek() == 'e') { @@ -120,12 +123,16 @@ if (!object_read_string(input, str)) break; - // if (last >= str) - // break; + if (last >= str) + object->set_internal_flags(Object::flag_unordered); - object_read_bencode(input, &object->as_map()[str], depth); + Object* value = &object->as_map()[str]; + object_read_bencode(input, value, depth); - // str.swap(last); + if (value->flags() & Object::flag_unordered) + object->set_internal_flags(Object::flag_unordered); + + str.swap(last); } break; Index: libtorrent/src/download/download_constructor.cc =================================================================== --- libtorrent/src/download/download_constructor.cc (revision 1093) +++ libtorrent/src/download/download_constructor.cc (working copy) @@ -132,6 +132,9 @@ if (!fileList->empty()) throw internal_error("parse_info received an already initialized Content object."); + if (b.flags() & Object::flag_unordered) + throw input_error("Download has unordered info dictionary."); + uint32_t chunkSize = b.get_key_value("piece length"); if (chunkSize <= (1 << 10) || chunkSize > (128 << 20))