From f6f516bed0a55cc8767509e3d2f551c0853a2b5a Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Mon, 6 Jun 2011 07:47:29 +0000 Subject: [PATCH] fix file_storage copy constructor (would break python bindings) --- include/libtorrent/file_storage.hpp | 4 ++ include/libtorrent/torrent_info.hpp | 6 ++- src/disk_io_thread.cpp | 3 +- src/file_storage.cpp | 6 +-- src/torrent_info.cpp | 72 ++++++++++++++++++++++++++--- 5 files changed, 79 insertions(+), 12 deletions(-) diff --git a/include/libtorrent/file_storage.hpp b/include/libtorrent/file_storage.hpp index e1501e67c..575c8b45e 100644 --- a/include/libtorrent/file_storage.hpp +++ b/include/libtorrent/file_storage.hpp @@ -77,6 +77,10 @@ namespace libtorrent struct TORRENT_EXPORT internal_file_entry { friend class file_storage; +#ifdef TORRENT_DEBUG + // for torrent_info::invariant_check + friend class torrent_info; +#endif internal_file_entry() : name(0) , offset(0) diff --git a/include/libtorrent/torrent_info.hpp b/include/libtorrent/torrent_info.hpp index 23170fc6d..8e556c26d 100644 --- a/include/libtorrent/torrent_info.hpp +++ b/include/libtorrent/torrent_info.hpp @@ -235,6 +235,10 @@ namespace libtorrent { public: +#ifdef TORRENT_DEBUG + void check_invariant() const; +#endif + #ifndef BOOST_NO_EXCEPTIONS torrent_info(lazy_entry const& torrent_file, int flags = 0); torrent_info(char const* buffer, int size, int flags = 0); @@ -405,7 +409,7 @@ namespace libtorrent bool is_merkle_torrent() const { return !m_merkle_tree.empty(); } // if we're logging member offsets, we need access to them -#if !defined NDEBUG \ +#if defined TORRENT_DEBUG \ && !defined TORRENT_LOGGING \ && !defined TORRENT_VERBOSE_LOGGING \ && !defined TORRENT_ERROR_LOGGING diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index 8f997cac7..055356545 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -823,8 +823,9 @@ namespace libtorrent { m_write_time.add_sample(total_microseconds(done - write_start) / num_write_calls); m_cache_stats.cumulative_write_time += total_milliseconds(done - write_start); - p.num_contiguous_blocks = contiguous_blocks(p); } + if (ret > 0) + p.num_contiguous_blocks = contiguous_blocks(p); TORRENT_ASSERT(buffer_size == 0); // std::cerr << " flushing p: " << p.piece << " cached_blocks: " << m_cache_stats.cache_size << std::endl; diff --git a/src/file_storage.cpp b/src/file_storage.cpp index f7c840801..49c8148fc 100644 --- a/src/file_storage.cpp +++ b/src/file_storage.cpp @@ -109,7 +109,7 @@ namespace libtorrent , symlink_attribute(fe.symlink_attribute) , path_index(fe.path_index) { - set_name(fe.name, fe.name_len); + set_name(fe.filename().c_str()); } internal_file_entry& internal_file_entry::operator=(internal_file_entry const& fe) @@ -122,7 +122,7 @@ namespace libtorrent hidden_attribute = fe.hidden_attribute; executable_attribute = fe.executable_attribute; symlink_attribute = fe.symlink_attribute; - set_name(fe.name, fe.name_len); + set_name(fe.filename().c_str()); return *this; } @@ -131,7 +131,7 @@ namespace libtorrent TORRENT_ASSERT(borrow_chars >= 0); if (borrow_chars > 1023) borrow_chars = 1023; if (name_len == 0) free((void*)name); - if (n == 0) + if (n == 0 || *n == 0) { TORRENT_ASSERT(borrow_chars == 0); name = 0; diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 7c7c40788..9538ed72f 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -63,6 +63,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/file.hpp" #include "libtorrent/utf8.hpp" #include "libtorrent/time.hpp" +#include "libtorrent/invariant_check.hpp" #if TORRENT_USE_I2P #include "libtorrent/parse_url.hpp" @@ -474,6 +475,9 @@ namespace libtorrent , m_private(t.m_private) , m_i2p(t.m_i2p) { +#if defined TORRENT_DEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS + t.check_invariant(); +#endif if (m_info_section_size > 0) { error_code ec; @@ -483,18 +487,19 @@ namespace libtorrent + m_info_section_size, m_info_dict, ec); TORRENT_ASSERT(ret == 0); - lazy_entry const* pieces = m_info_dict.dict_find_string("pieces"); - if (pieces && pieces->string_length() == m_files.num_pieces() * 20) - { - m_piece_hashes = m_info_section.get() + (pieces->string_ptr() - m_info_section.get()); - TORRENT_ASSERT(m_piece_hashes >= m_info_section.get()); - TORRENT_ASSERT(m_piece_hashes < m_info_section.get() + m_info_section_size); - } + ptrdiff_t offset = m_info_section.get() - t.m_info_section.get(); + + m_piece_hashes += offset; + TORRENT_ASSERT(m_piece_hashes >= m_info_section.get()); + TORRENT_ASSERT(m_piece_hashes < m_info_section.get() + m_info_section_size); } + INVARIANT_CHECK; } void torrent_info::remap_files(file_storage const& f) { + INVARIANT_CHECK; + // the new specified file storage must have the exact // same size as the current file storage TORRENT_ASSERT(m_files.total_size() == f.total_size()); @@ -536,6 +541,7 @@ namespace libtorrent #else parse_torrent_file(e, ec, 0); #endif + INVARIANT_CHECK; } #endif @@ -552,6 +558,8 @@ namespace libtorrent error_code ec; if (!parse_torrent_file(torrent_file, ec, flags)) throw invalid_torrent_file(ec); + + INVARIANT_CHECK; } torrent_info::torrent_info(char const* buffer, int size, int flags) @@ -570,6 +578,8 @@ namespace libtorrent if (!parse_torrent_file(e, ec, flags)) throw invalid_torrent_file(ec); + + INVARIANT_CHECK; } torrent_info::torrent_info(std::string const& filename, int flags) @@ -591,6 +601,8 @@ namespace libtorrent if (!parse_torrent_file(e, ec, flags)) throw invalid_torrent_file(ec); + + INVARIANT_CHECK; } #if TORRENT_USE_WSTRING @@ -616,6 +628,8 @@ namespace libtorrent if (!parse_torrent_file(e, ec, flags)) throw invalid_torrent_file(ec); + + INVARIANT_CHECK; } #endif #endif @@ -629,6 +643,8 @@ namespace libtorrent , m_i2p(false) { parse_torrent_file(torrent_file, ec, flags); + + INVARIANT_CHECK; } torrent_info::torrent_info(char const* buffer, int size, error_code& ec, int flags) @@ -644,6 +660,8 @@ namespace libtorrent if (lazy_bdecode(buffer, buffer + size, e, ec) != 0) return; parse_torrent_file(e, ec, flags); + + INVARIANT_CHECK; } torrent_info::torrent_info(std::string const& filename, error_code& ec, int flags) @@ -663,6 +681,8 @@ namespace libtorrent if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0) return; parse_torrent_file(e, ec, flags); + + INVARIANT_CHECK; } #if TORRENT_USE_WSTRING @@ -685,6 +705,8 @@ namespace libtorrent if (buf.size() == 0 || lazy_bdecode(&buf[0], &buf[0] + buf.size(), e, ec) != 0) return; parse_torrent_file(e, ec, flags); + + INVARIANT_CHECK; } #endif @@ -708,6 +730,8 @@ namespace libtorrent void torrent_info::copy_on_write() { + INVARIANT_CHECK; + if (m_orig_files) return; m_orig_files.reset(new file_storage(m_files)); } @@ -719,6 +743,8 @@ namespace libtorrent void torrent_info::swap(torrent_info& ti) { + INVARIANT_CHECK; + using std::swap; m_urls.swap(ti.m_urls); m_web_seeds.swap(ti.m_web_seeds); @@ -912,6 +938,8 @@ namespace libtorrent bool torrent_info::add_merkle_nodes(std::map const& subtree , int piece) { + INVARIANT_CHECK; + int n = m_merkle_first_leaf + piece; typedef std::map::const_iterator iter; iter i = subtree.find(n); @@ -962,6 +990,8 @@ namespace libtorrent // the given piece std::map torrent_info::build_merkle_list(int piece) const { + INVARIANT_CHECK; + std::map ret; int n = m_merkle_first_leaf + piece; ret[n] = m_merkle_tree[n]; @@ -1203,6 +1233,8 @@ namespace libtorrent void torrent_info::print(std::ostream& os) const { + INVARIANT_CHECK; + os << "trackers:\n"; for (std::vector::const_iterator i = trackers().begin(); i != trackers().end(); ++i) @@ -1222,5 +1254,31 @@ namespace libtorrent // ------- end deprecation ------- #endif +#ifdef TORRENT_DEBUG + void torrent_info::check_invariant() const + { + for (file_storage::iterator i = m_files.begin() + , end(m_files.end()); i != end; ++i) + { + TORRENT_ASSERT(i->name != 0); + if (i->name_len > 0) + { + // name needs to point into the allocated info section buffer + TORRENT_ASSERT(i->name >= m_info_section.get()); + TORRENT_ASSERT(i->name < m_info_section.get() + m_info_section_size); + } + else + { + // name must be a valid string + TORRENT_ASSERT(strlen(i->name) < 2048); + } + } + + TORRENT_ASSERT(m_piece_hashes); + TORRENT_ASSERT(m_piece_hashes >= m_info_section.get()); + TORRENT_ASSERT(m_piece_hashes < m_info_section.get() + m_info_section_size); + } +#endif + }