diff --git a/bindings/python/src/session.cpp b/bindings/python/src/session.cpp index fb02fead0..9b0adc425 100644 --- a/bindings/python/src/session.cpp +++ b/bindings/python/src/session.cpp @@ -18,6 +18,8 @@ #include #include // for sign_mutable_item #include +#include + #include #include #include @@ -344,6 +346,28 @@ namespace return ret; } + list cached_piece_info_list(std::vector const& v) + { + list pieces; + time_point now = clock_type::now(); + for (std::vector::const_iterator i = v.begin() + , end(v.end()); i != end; ++i) + { + dict d; + d["piece"] = i->piece; + d["last_use"] = total_milliseconds(now - i->last_use) / 1000.f; + d["next_to_hash"] = i->next_to_hash; + d["kind"] = i->kind; + pieces.append(d); + } + return pieces; + } + + list cache_status_pieces(cache_status const& cs) + { + return cached_piece_info_list(cs.pieces); + } + #ifndef TORRENT_NO_DEPRECATE cache_status get_cache_status(lt::session& s) { @@ -372,19 +396,7 @@ namespace ses.get_cache_info(ih, ret); } - list pieces; - time_point now = clock_type::now(); - for (std::vector::iterator i = ret.begin() - , end(ret.end()); i != end; ++i) - { - dict d; - d["piece"] = i->piece; - d["last_use"] = total_milliseconds(now - i->last_use) / 1000.f; - d["next_to_hash"] = i->next_to_hash; - d["kind"] = i->kind; - pieces.append(d); - } - return pieces; + return cached_piece_info_list(ret); } #endif @@ -646,6 +658,7 @@ void bind_session() #endif ; class_("cache_status") + .add_property("pieces", cache_status_pieces) #ifndef TORRENT_NO_DEPRECATE .def_readonly("blocks_written", &cache_status::blocks_written) .def_readonly("writes", &cache_status::writes) diff --git a/bindings/python/test.py b/bindings/python/test.py index 94edc3c29..886d4b80b 100644 --- a/bindings/python/test.py +++ b/bindings/python/test.py @@ -73,6 +73,14 @@ class test_torrent_handle(unittest.TestCase): # from python h.scrape_tracker() + def test_cache_info(self): + ses = lt.session({'alert_mask': lt.alert.category_t.all_categories, 'enable_dht': False}) + ti = lt.torrent_info('url_seed_multi.torrent'); + h = ses.add_torrent({'ti': ti, 'save_path': os.getcwd()}) + + cs = ses.get_cache_info(h) + self.assertEqual(cs.pieces, []) + class test_torrent_info(unittest.TestCase): def test_bencoded_constructor(self): diff --git a/include/libtorrent/stack_allocator.hpp b/include/libtorrent/stack_allocator.hpp index 2d2bcadcb..647ec1ad2 100644 --- a/include/libtorrent/stack_allocator.hpp +++ b/include/libtorrent/stack_allocator.hpp @@ -81,7 +81,11 @@ namespace libtorrent { namespace aux #pragma clang diagnostic pop #endif - if (len < 0) return copy_string("(format error)"); + if (len < 0) + { + m_storage.resize(ret); + return copy_string("(format error)"); + } // +1 is to include the 0-terminator m_storage.resize(ret + (len > 512 ? 512 : len) + 1); @@ -92,6 +96,7 @@ namespace libtorrent { namespace aux { int const ret = int(m_storage.size()); int const size = int(buf.size()); + if (size < 1) return -1; m_storage.resize(ret + size); std::memcpy(&m_storage[ret], buf.data(), size); return ret; @@ -99,7 +104,7 @@ namespace libtorrent { namespace aux int allocate(int const bytes) { - TORRENT_ASSERT(bytes >= 0); + if (bytes < 1) return -1; int const ret = int(m_storage.size()); m_storage.resize(ret + bytes); return ret; @@ -107,14 +112,14 @@ namespace libtorrent { namespace aux char* ptr(int const idx) { - TORRENT_ASSERT(idx >= 0); + if(idx < 0) return NULL; TORRENT_ASSERT(idx < int(m_storage.size())); return &m_storage[idx]; } char const* ptr(int const idx) const { - TORRENT_ASSERT(idx >= 0); + if(idx < 0) return NULL; TORRENT_ASSERT(idx < int(m_storage.size())); return &m_storage[idx]; } diff --git a/test/test_stack_allocator.cpp b/test/test_stack_allocator.cpp index 9493ad48b..2f0fd7240 100644 --- a/test/test_stack_allocator.cpp +++ b/test/test_stack_allocator.cpp @@ -59,6 +59,14 @@ TORRENT_TEST(copy_buffer) a.allocate(100000); TEST_CHECK(strcmp(a.ptr(idx1), "testing") == 0); + + // attempt zero size allocation + int const idx2 = a.copy_buffer("nothing", 0); + TEST_CHECK(idx2 == -1); + + // attempt to get a pointer after zero allocation + char* ptr = a.ptr(idx2); + TEST_CHECK(ptr == NULL); } TORRENT_TEST(allocate) @@ -75,6 +83,14 @@ TORRENT_TEST(allocate) ptr = a.ptr(idx1); for (int i = 0; i < 100; ++i) TEST_CHECK(ptr[i] == char(i % 256)); + + // attempt zero size allocation + int const idx2 = a.allocate(0); + TEST_CHECK(idx2 == -1); + + // attempt to get a pointer after zero allocation + ptr = a.ptr(idx2); + TEST_CHECK(ptr == NULL); } TORRENT_TEST(swap)