Date: Thursday, July 21, 2016 @ 08:57:24 Author: heftig Revision: 272080
1.1-3 Added: libtorrent-rasterbar/trunk/libtorrent-rasterbar-1.1.0-fix-get-ip-filter.patch libtorrent-rasterbar/trunk/libtorrent-rasterbar-1.1.0-fix-invalid-input-crash.patch libtorrent-rasterbar/trunk/libtorrent-rasterbar-1.1.0-python-fixes.patch Modified: libtorrent-rasterbar/trunk/PKGBUILD Deleted: libtorrent-rasterbar/trunk/boost-1.60.patch ----------------------------------------------------------+ PKGBUILD | 62 ++- boost-1.60.patch | 22 - libtorrent-rasterbar-1.1.0-fix-get-ip-filter.patch | 31 + libtorrent-rasterbar-1.1.0-fix-invalid-input-crash.patch | 262 +++++++++++++ libtorrent-rasterbar-1.1.0-python-fixes.patch | 50 ++ 5 files changed, 388 insertions(+), 39 deletions(-) Modified: PKGBUILD =================================================================== --- PKGBUILD 2016-07-21 01:30:43 UTC (rev 272079) +++ PKGBUILD 2016-07-21 08:57:24 UTC (rev 272080) @@ -5,37 +5,65 @@ pkgname=libtorrent-rasterbar pkgver=1.1 -pkgrel=2 +pkgrel=3 epoch=1 pkgdesc="A C++ BitTorrent library that aims to be a good alternative to all the other implementations around" url="http://www.rasterbar.com/products/libtorrent/" arch=('i686' 'x86_64') license=('BSD') -depends=('boost-libs' 'geoip' 'python2') -makedepends=('boost') +depends=('boost-libs') +makedepends=('boost' 'python2' 'python3') options=('!emptydirs') -source=(https://github.com/arvidn/libtorrent/archive/libtorrent-${pkgver//./_}/$pkgname-$pkgver.tar.gz) -sha1sums=('ac6e871d3b71a56e849ab1fc6369165a80acfd32') +_pkgver=${pkgver//./_} +source=(https://github.com/arvidn/libtorrent/archive/libtorrent-${_pkgver}/$pkgname-$pkgver.tar.gz + libtorrent-rasterbar-1.1.0-fix-get-ip-filter.patch + libtorrent-rasterbar-1.1.0-python-fixes.patch + libtorrent-rasterbar-1.1.0-fix-invalid-input-crash.patch) +sha1sums=('ac6e871d3b71a56e849ab1fc6369165a80acfd32' + 'b05f12f7d43960273b2d7e15aeeeb2bbc755b58b' + '5ade010320bde598f48351f0659f88d9d980fad4' + '3dd8a74d5ce785755efbf8fc10d3013bba4bc261') prepare() { - # https://github.com/qbittorrent/qBittorrent/issues/5265#issuecomment-220007436 - export CXXFLAGS="$CXXFLAGS -std=c++11" + mkdir py2 py3 + cd libtorrent-libtorrent-${_pkgver} + + # Backports from master, patches sourced from + # https://build.opensuse.org/package/show/devel:libraries:c_c++/libtorrent-rasterbar + patch -Np1 -i ../libtorrent-rasterbar-1.1.0-fix-get-ip-filter.patch + patch -Np1 -i ../libtorrent-rasterbar-1.1.0-python-fixes.patch + patch -Np1 -i ../libtorrent-rasterbar-1.1.0-fix-invalid-input-crash.patch + + # Avoid depending on newer processors + sed -i 's/-msse4.2//' configure.ac + + ./autotool.sh } -build() { - cd libtorrent-libtorrent-${pkgver//./_} - ./autotool.sh - PYTHON=/usr/bin/python2 \ - ./configure \ +_build() ( + cd py$1 + # https://github.com/qbittorrent/qBittorrent/issues/5265#issuecomment-220007436 + CXXFLAGS="$CXXFLAGS -std=c++11" \ + PYTHON=/usr/bin/python$1 \ + ../libtorrent-libtorrent-${_pkgver}/configure \ --prefix=/usr \ --enable-python-binding \ - --with-libgeoip=system \ + --enable-examples \ + --disable-static \ --with-libiconv - make +) + +build() { + _build 2 + _build 3 } package() { - cd libtorrent-libtorrent-${pkgver//./_} - make DESTDIR="$pkgdir" install - install -Dm644 COPYING "$pkgdir/usr/share/licenses/$pkgname/LICENSE" + make -C py2 DESTDIR="$pkgdir" install + make -C py3 DESTDIR="$pkgdir" install + install -Dm644 libtorrent-libtorrent-${_pkgver}/COPYING \ + "$pkgdir/usr/share/licenses/$pkgname/LICENSE" + + # Remove most example binaries + rm "$pkgdir"/usr/bin/{*_test,*_tester,simple_client,stats_counters} } Deleted: boost-1.60.patch =================================================================== --- boost-1.60.patch 2016-07-21 01:30:43 UTC (rev 272079) +++ boost-1.60.patch 2016-07-21 08:57:24 UTC (rev 272080) @@ -1,22 +0,0 @@ -From 5330ba5af717b983e456be9f576d66b78d9ca214 Mon Sep 17 00:00:00 2001 -From: Andrew Resch <andrewre...@gmail.com> -Date: Sat, 2 Jan 2016 14:40:02 -0800 -Subject: [PATCH] register_ptr_to_python for boost::shared_ptr<alert> - ---- - bindings/python/src/session.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/bindings/python/src/session.cpp b/bindings/python/src/session.cpp -index fe53e10..727a54a 100644 ---- a/bindings/python/src/session.cpp -+++ b/bindings/python/src/session.cpp -@@ -799,7 +799,7 @@ void bind_session() - .def("settings", &get_feed_settings) - ; - -- register_ptr_to_python<std::auto_ptr<alert> >(); -+ register_ptr_to_python<boost::shared_ptr<alert> >(); - - def("high_performance_seed", high_performance_seed); - def("min_memory_usage", min_memory_usage); Added: libtorrent-rasterbar-1.1.0-fix-get-ip-filter.patch =================================================================== --- libtorrent-rasterbar-1.1.0-fix-get-ip-filter.patch (rev 0) +++ libtorrent-rasterbar-1.1.0-fix-get-ip-filter.patch 2016-07-21 08:57:24 UTC (rev 272080) @@ -0,0 +1,31 @@ +--- a/src/session_impl.cpp ++++ b/src/session_impl.cpp +@@ -1237,6 +1237,7 @@ namespace aux { + ip_filter const& session_impl::get_ip_filter() + { + TORRENT_ASSERT(is_single_thread()); ++ if (!m_ip_filter) m_ip_filter = boost::make_shared<ip_filter>(); + return *m_ip_filter; + } + +--- a/test/test_ip_filter.cpp ++++ b/test/test_ip_filter.cpp +@@ -89,6 +89,18 @@ void test_rules_invariant(std::vector<ip + } + } + ++TORRENT_TEST(session_get_ip_filter) ++{ ++ using namespace libtorrent; ++ session ses; ++ ip_filter const& ipf = ses.get_ip_filter(); ++#if TORRENT_USE_IPV6 ++ TEST_EQUAL(boost::get<0>(ipf.export_filter()).size(), 1); ++#else ++ TEST_EQUAL(ipf.export_filter().size(), 1); ++#endif ++} ++ + TORRENT_TEST(ip_filter) + { + using namespace libtorrent; Added: libtorrent-rasterbar-1.1.0-fix-invalid-input-crash.patch =================================================================== --- libtorrent-rasterbar-1.1.0-fix-invalid-input-crash.patch (rev 0) +++ libtorrent-rasterbar-1.1.0-fix-invalid-input-crash.patch 2016-07-21 08:57:24 UTC (rev 272080) @@ -0,0 +1,262 @@ +--- a/src/http_parser.cpp ++++ b/src/http_parser.cpp +@@ -174,6 +174,7 @@ restart_response: + if (m_state == read_status) + { + TORRENT_ASSERT(!m_finished); ++ TORRENT_ASSERT(pos <= recv_buffer.end); + char const* newline = std::find(pos, recv_buffer.end, '\n'); + // if we don't have a full line yet, wait. + if (newline == recv_buffer.end) +@@ -194,6 +195,7 @@ restart_response: + + char const* line = pos; + ++newline; ++ TORRENT_ASSERT(newline >= pos); + int incoming = int(newline - pos); + m_recv_pos += incoming; + boost::get<1>(ret) += newline - (m_recv_buffer.begin + start_pos); +@@ -227,6 +229,7 @@ restart_response: + if (m_state == read_header) + { + TORRENT_ASSERT(!m_finished); ++ TORRENT_ASSERT(pos <= recv_buffer.end); + char const* newline = std::find(pos, recv_buffer.end, '\n'); + std::string line; + +@@ -277,6 +280,12 @@ restart_response: + if (name == "content-length") + { + m_content_length = strtoll(value.c_str(), 0, 10); ++ if (m_content_length < 0) ++ { ++ m_state = error_state; ++ error = true; ++ return ret; ++ } + } + else if (name == "connection") + { +@@ -294,12 +303,24 @@ restart_response: + if (string_begins_no_case("bytes ", ptr)) ptr += 6; + char* end; + m_range_start = strtoll(ptr, &end, 10); ++ if (m_range_start < 0) ++ { ++ m_state = error_state; ++ error = true; ++ return ret; ++ } + if (end == ptr) success = false; + else if (*end != '-') success = false; + else + { + ptr = end + 1; + m_range_end = strtoll(ptr, &end, 10); ++ if (m_range_end < 0) ++ { ++ m_state = error_state; ++ error = true; ++ return ret; ++ } + if (end == ptr) success = false; + } + +@@ -318,6 +339,7 @@ restart_response: + } + + TORRENT_ASSERT(m_recv_pos <= recv_buffer.left()); ++ TORRENT_ASSERT(pos <= recv_buffer.end); + newline = std::find(pos, recv_buffer.end, '\n'); + } + boost::get<1>(ret) += newline - (m_recv_buffer.begin + start_pos); +@@ -347,6 +369,12 @@ restart_response: + int header_size; + if (parse_chunk_header(buf, &chunk_size, &header_size)) + { ++ if (chunk_size < 0) ++ { ++ m_state = error_state; ++ error = true; ++ return ret; ++ } + if (chunk_size > 0) + { + std::pair<boost::int64_t, boost::int64_t> chunk_range(m_cur_chunk_end + header_size +@@ -419,6 +447,7 @@ restart_response: + bool http_parser::parse_chunk_header(buffer::const_interval buf + , boost::int64_t* chunk_size, int* header_size) + { ++ TORRENT_ASSERT(buf.begin <= buf.end); + char const* pos = buf.begin; + + // ignore one optional new-line. This is since each chunk +@@ -429,6 +458,7 @@ restart_response: + if (pos < buf.end && pos[0] == '\n') ++pos; + if (pos == buf.end) return false; + ++ TORRENT_ASSERT(pos <= buf.end); + char const* newline = std::find(pos, buf.end, '\n'); + if (newline == buf.end) return false; + ++newline; +@@ -441,6 +471,8 @@ restart_response: + + // first, read the chunk length + *chunk_size = strtoll(pos, 0, 16); ++ if (*chunk_size < 0) return true; ++ + if (*chunk_size != 0) + { + *header_size = newline - buf.begin; +--- a/test/test_http_parser.cpp ++++ b/test/test_http_parser.cpp +@@ -361,29 +361,6 @@ TORRENT_TEST(http_parser) + TEST_EQUAL(parser.headers().find("test2")->second, "bar"); + } + +- // test chunked encoding +- +- parser.reset(); +- +- char const* chunked_input = +- "HTTP/1.1 200 OK\r\n" +- "Transfer-Encoding: chunked\r\n" +- "Content-Type: text/plain\r\n" +- "\r\n" +- "4\r\ntest\r\n4\r\n1234\r\n10\r\n0123456789abcdef\r\n" +- "0\r\n\r\n"; +- received = feed_bytes(parser, chunked_input); +- +- TEST_EQUAL(strlen(chunked_input), 24 + 94) +- TEST_CHECK(received == make_tuple(24, 94, false)); +- TEST_CHECK(parser.finished()); +- +- char mutable_buffer[100]; +- memcpy(mutable_buffer, parser.get_body().begin, parser.get_body().left()); +- int len = parser.collapse_chunk_headers(mutable_buffer, parser.get_body().left()); +- +- TEST_CHECK(std::equal(mutable_buffer, mutable_buffer + len, "test12340123456789abcdef")); +- + // test url parsing + + error_code ec; +@@ -476,3 +453,119 @@ TORRENT_TEST(http_parser) + TEST_EQUAL(is_redirect(400), false); + } + ++TORRENT_TEST(chunked_encoding) ++{ ++ char const* chunked_input = ++ "HTTP/1.1 200 OK\r\n" ++ "Transfer-Encoding: chunked\r\n" ++ "Content-Type: text/plain\r\n" ++ "\r\n" ++ "4\r\ntest\r\n4\r\n1234\r\n10\r\n0123456789abcdef\r\n" ++ "0\r\n\r\n"; ++ ++ http_parser parser; ++ boost::tuple<int, int, bool> const received ++ = feed_bytes(parser, chunked_input); ++ ++ TEST_EQUAL(strlen(chunked_input), 24 + 94) ++ TEST_CHECK(received == make_tuple(24, 94, false)); ++ TEST_CHECK(parser.finished()); ++ ++ char mutable_buffer[100]; ++ memcpy(mutable_buffer, parser.get_body().begin, parser.get_body().left()); ++ int len = parser.collapse_chunk_headers(mutable_buffer, parser.get_body().left()); ++ ++ TEST_CHECK(std::equal(mutable_buffer, mutable_buffer + len, "test12340123456789abcdef")); ++} ++ ++TORRENT_TEST(invalid_content_length) ++{ ++ char const* chunked_input = ++ "HTTP/1.1 200 OK\r\n" ++ "Transfer-Encoding: chunked\r\n" ++ "Content-Length: -45345\r\n" ++ "\r\n"; ++ ++ http_parser parser; ++ boost::tuple<int, int, bool> const received ++ = feed_bytes(parser, chunked_input); ++ ++ TEST_CHECK(boost::get<2>(received) == true); ++} ++ ++TORRENT_TEST(invalid_chunked) ++{ ++ char const* chunked_input = ++ "HTTP/1.1 200 OK\r\n" ++ "Transfer-Encoding: chunked\r\n" ++ "\r\n" ++ "-53465234545\r\n" ++ "foobar"; ++ ++ http_parser parser; ++ boost::tuple<int, int, bool> const received ++ = feed_bytes(parser, chunked_input); ++ ++ TEST_CHECK(boost::get<2>(received) == true); ++} ++ ++TORRENT_TEST(invalid_content_range_start) ++{ ++ char const* chunked_input = ++ "HTTP/1.1 206 OK\n" ++ "Content-Range: bYTes -3-4\n" ++ "\n"; ++ ++ http_parser parser; ++ boost::tuple<int, int, bool> const received ++ = feed_bytes(parser, chunked_input); ++ ++ TEST_CHECK(boost::get<2>(received) == true); ++} ++ ++TORRENT_TEST(invalid_content_range_end) ++{ ++ char const* chunked_input = ++ "HTTP/1.1 206 OK\n" ++ "Content-Range: bYTes 3--434\n" ++ "\n"; ++ ++ http_parser parser; ++ boost::tuple<int, int, bool> const received ++ = feed_bytes(parser, chunked_input); ++ ++ TEST_CHECK(boost::get<2>(received) == true); ++} ++ ++TORRENT_TEST(invalid_chunk_afl) ++{ ++ boost::uint8_t const invalid_chunked_input[] = { ++ 0x48, 0x6f, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, // HoTP/1.1 200 OK ++ 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, // Cont-Length: 20 ++ 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x2d, 0x4c, 0x65, // Contente: tn ++ 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, // Transfer-Encoding: chunked ++ 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, // ++ 0x74, 0x65, 0x3a, 0x20, 0x74, 0x6e, 0x0d, 0x0a, // ++ 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, // ++ 0x2d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, // -89abc9abcdef ++ 0x67, 0x3a, 0x20, 0x63, 0x68, 0x75, 0x6e, 0x6b, // � ++ 0x65, 0x64, 0x0d, 0x0a, 0x0d, 0x0d, 0x0a, 0x0d, // T����������def ++ 0x0a, 0x0a, 0x2d, 0x38, 0x39, 0x61, 0x62, 0x63, // � ++ 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x0d, // T�����������est-headyr: foobar ++ 0x0a, 0xd6, 0x0d, 0x0a, 0x54, 0xbd, 0xbd, 0xbd, ++ 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0x64, ++ 0x65, 0x66, 0x0d, 0x0a, 0xd6, 0x0d, 0x0a, 0x54, ++ 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, ++ 0xbd, 0xbd, 0xbd, 0x65, 0x73, 0x74, 0x2d, 0x68, ++ 0x65, 0x61, 0x64, 0x79, 0x72, 0x3a, 0x20, 0x66, ++ 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x0d, 0x0a, 0x0d, ++ 0x0a, 0x00 ++ }; ++ ++ http_parser parser; ++ boost::tuple<int, int, bool> const received ++ = feed_bytes(parser, reinterpret_cast<char const*>(invalid_chunked_input)); ++ ++ TEST_CHECK(boost::get<2>(received) == true); ++} ++ Added: libtorrent-rasterbar-1.1.0-python-fixes.patch =================================================================== --- libtorrent-rasterbar-1.1.0-python-fixes.patch (rev 0) +++ libtorrent-rasterbar-1.1.0-python-fixes.patch 2016-07-21 08:57:24 UTC (rev 272080) @@ -0,0 +1,50 @@ +--- a/bindings/python/src/session.cpp ++++ b/bindings/python/src/session.cpp +@@ -106,7 +106,7 @@ namespace + std::string key = extract<std::string>(iterkeys[i]); + + int sett = setting_by_name(key); +- if (sett == 0) continue; ++ if (sett < 0) continue; + + TORRENT_TRY + { +@@ -810,7 +810,7 @@ void bind_session() + #ifndef TORRENT_NO_DEPRECATE + .def("add_feed", &add_feed) + .def("status", allow_threads(<::session::status)) +- .def("settings", &session_get_settings) ++ .def("settings", <::session::settings) + .def("set_settings", &session_set_settings) + #endif + .def("get_settings", &session_get_settings) +--- a/bindings/python/src/torrent_handle.cpp ++++ b/bindings/python/src/torrent_handle.cpp +@@ -193,9 +193,9 @@ void dict_to_announce_entry(dict d, anno + if (d.has_key("source")) + ae.source = extract<int>(d["source"]); + if (d.has_key("verified")) +- ae.verified = extract<int>(d["verified"]); ++ ae.verified = extract<bool>(d["verified"]); + if (d.has_key("send_stats")) +- ae.send_stats = extract<int>(d["send_stats"]); ++ ae.send_stats = extract<bool>(d["send_stats"]); + } + + void replace_trackers(torrent_handle& h, object trackers) +--- a/bindings/python/src/torrent_info.cpp ++++ b/bindings/python/src/torrent_info.cpp +@@ -113,10 +113,10 @@ namespace + + int get_tier(announce_entry const& ae) { return ae.tier; } + void set_tier(announce_entry& ae, int v) { ae.tier = v; } +- bool get_fail_limit(announce_entry const& ae) { return ae.fail_limit; } ++ int get_fail_limit(announce_entry const& ae) { return ae.fail_limit; } + void set_fail_limit(announce_entry& ae, int l) { ae.fail_limit = l; } +- bool get_fails(announce_entry const& ae) { return ae.fails; } +- bool get_source(announce_entry const& ae) { return ae.source; } ++ int get_fails(announce_entry const& ae) { return ae.fails; } ++ int get_source(announce_entry const& ae) { return ae.source; } + bool get_verified(announce_entry const& ae) { return ae.verified; } + bool get_updating(announce_entry const& ae) { return ae.updating; } + bool get_start_sent(announce_entry const& ae) { return ae.start_sent; }