From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 4D7A5138334 for ; Sun, 6 Oct 2019 17:42:16 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 9EDDCE085A; Sun, 6 Oct 2019 17:42:14 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 762A9E085A for ; Sun, 6 Oct 2019 17:42:14 +0000 (UTC) Received: from oystercatcher.gentoo.org (unknown [IPv6:2a01:4f8:202:4333:225:90ff:fed9:fc84]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 33F8A34B9DA for ; Sun, 6 Oct 2019 17:42:13 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 9C92B82F for ; Sun, 6 Oct 2019 17:42:09 +0000 (UTC) From: "Andreas Sturmlechner" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Andreas Sturmlechner" Message-ID: <1570383710.e62a01696afc68d159e2050fcc38602ee64190e3.asturm@gentoo> Subject: [gentoo-commits] repo/gentoo:master commit in: net-p2p/ktorrent/, net-p2p/ktorrent/files/ X-VCS-Repository: repo/gentoo X-VCS-Files: net-p2p/ktorrent/files/ktorrent-5.1.2-crash-on-exit.patch net-p2p/ktorrent/ktorrent-5.1.2-r2.ebuild X-VCS-Directories: net-p2p/ktorrent/files/ net-p2p/ktorrent/ X-VCS-Committer: asturm X-VCS-Committer-Name: Andreas Sturmlechner X-VCS-Revision: e62a01696afc68d159e2050fcc38602ee64190e3 X-VCS-Branch: master Date: Sun, 6 Oct 2019 17:42:09 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 2b82889e-ddf2-4115-aa11-9432714d0151 X-Archives-Hash: 1dcd744808ca1ed5aaa5b60344554815 commit: e62a01696afc68d159e2050fcc38602ee64190e3 Author: Andreas Sturmlechner gentoo org> AuthorDate: Sun Oct 6 17:39:53 2019 +0000 Commit: Andreas Sturmlechner gentoo org> CommitDate: Sun Oct 6 17:41:50 2019 +0000 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=e62a0169 net-p2p/ktorrent: Fix crash on exit Closes: https://bugs.gentoo.org/632588 Package-Manager: Portage-2.3.76, Repoman-2.3.17 Signed-off-by: Andreas Sturmlechner gentoo.org> .../files/ktorrent-5.1.2-crash-on-exit.patch | 386 +++++++++++++++++++++ net-p2p/ktorrent/ktorrent-5.1.2-r2.ebuild | 106 ++++++ 2 files changed, 492 insertions(+) diff --git a/net-p2p/ktorrent/files/ktorrent-5.1.2-crash-on-exit.patch b/net-p2p/ktorrent/files/ktorrent-5.1.2-crash-on-exit.patch new file mode 100644 index 00000000000..5cb6640d16f --- /dev/null +++ b/net-p2p/ktorrent/files/ktorrent-5.1.2-crash-on-exit.patch @@ -0,0 +1,386 @@ +From b819ef6a35495e12a204cbb241cdb2502c4cd11e Mon Sep 17 00:00:00 2001 +From: Valerii Malov +Date: Sun, 22 Sep 2019 21:20:47 +0300 +Subject: Cleanup ViewModel a bit and try to fix crash on exit + +Summary: +removeTorrent makes changes to torrent list we are currently iterating +on per-item basis, this causees heap-use-after-free in onExit +Just call removeRows which should be functionally the same, but should +delete all items in one batch + +CCBUG: 383127 + +Compact ViewModel::Item::update +Fix a few warnings (0 as nullptr, c-style casts) +Remove useless ViewModel::torrentFromIndex variant +Remove unused headers +add CMakeLists.txt.user to gitignore + +Test Plan: build with asan, run & exit, see asan stacktrace before changing onExit + +Reviewers: stikonas + +Differential Revision: https://phabricator.kde.org/D24149 +--- + .gitignore | 1 + + ktorrent/CMakeLists.txt | 1 + + ktorrent/view/viewmodel.cpp | 197 ++++++++++++-------------------------------- + ktorrent/view/viewmodel.h | 21 +++-- + 4 files changed, 63 insertions(+), 157 deletions(-) + +diff --git a/.gitignore b/.gitignore +index 2ad76d6..d88e731 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -1,3 +1,4 @@ + build + .kdev4/ + ktorrent.kdev4 ++CMakeLists.txt.user +diff --git a/ktorrent/CMakeLists.txt b/ktorrent/CMakeLists.txt +index 75ba8a1..bf605a5 100644 +--- a/ktorrent/CMakeLists.txt ++++ b/ktorrent/CMakeLists.txt +@@ -91,6 +91,7 @@ set(KTORRENT_ICONS_PNG + ecm_add_app_icon(ktorrent_SRC ICONS ${KTORRENT_ICONS_PNG}) + + add_executable(ktorrent_app ${ktorrent_SRC}) ++set_property(TARGET ktorrent_app PROPERTY CXX_STANDARD 14) + set_target_properties(ktorrent_app PROPERTIES OUTPUT_NAME ktorrent) + + target_link_libraries(ktorrent_app +diff --git a/ktorrent/view/viewmodel.cpp b/ktorrent/view/viewmodel.cpp +index 6834186..b9feeab 100644 +--- a/ktorrent/view/viewmodel.cpp ++++ b/ktorrent/view/viewmodel.cpp +@@ -32,18 +32,17 @@ + + #include + +-#include +-#include +-#include ++#include + #include +-#include +-#include + #include +-#include ++#include ++#include ++#include ++ + #include "core.h" +-#include "viewdelegate.h" +-#include "view.h" + #include "settings.h" ++#include "view.h" ++#include "viewdelegate.h" + + using namespace bt; + +@@ -80,125 +79,45 @@ namespace kt + { + bool ret = false; + const TorrentStats& s = tc->getStats(); +- if (status != s.status) +- { +- to_update.append(model->index(row, NAME)); +- status = s.status; +- if (sort_column == NAME) +- ret = true; +- } +- +- if (bytes_downloaded != s.bytes_downloaded) +- { +- to_update.append(model->index(row, BYTES_DOWNLOADED)); +- bytes_downloaded = s.bytes_downloaded; +- if (sort_column == BYTES_DOWNLOADED) +- ret = true; +- } +- +- if (total_bytes_to_download != s.total_bytes_to_download) +- { +- to_update.append(model->index(row, TOTAL_BYTES_TO_DOWNLOAD)); +- total_bytes_to_download = s.total_bytes_to_download; +- if (sort_column == TOTAL_BYTES_TO_DOWNLOAD) +- ret = true; +- } +- +- if (bytes_uploaded != s.bytes_uploaded) +- { +- to_update.append(model->index(row, BYTES_UPLOADED)); +- bytes_uploaded = s.bytes_uploaded; +- if (sort_column == BYTES_UPLOADED) +- ret = true; +- } +- +- if (bytes_left != s.bytes_left_to_download) +- { +- to_update.append(model->index(row, BYTES_LEFT)); +- bytes_left = s.bytes_left_to_download; +- if (sort_column == BYTES_LEFT) +- ret = true; +- } +- +- if (download_rate != s.download_rate) +- { +- to_update.append(model->index(row, DOWNLOAD_RATE)); +- download_rate = s.download_rate; +- if (sort_column == DOWNLOAD_RATE) +- ret = true; +- } +- +- if (upload_rate != s.upload_rate) +- { +- to_update.append(model->index(row, UPLOAD_RATE)); +- upload_rate = s.upload_rate; +- if (sort_column == UPLOAD_RATE) +- ret = true; +- } + +- int neta = tc->getETA(); +- if (eta != neta) +- { +- to_update.append(model->index(row, ETA)); +- eta = neta; +- if (sort_column == ETA) +- ret = true; +- } +- +- if (seeders_connected_to != s.seeders_connected_to || seeders_total != s.seeders_total) +- { +- to_update.append(model->index(row, SEEDERS)); +- seeders_connected_to = s.seeders_connected_to; +- seeders_total = s.seeders_total; +- if (sort_column == SEEDERS) +- ret = true; +- } +- +- if (leechers_total != s.leechers_total || leechers_connected_to != s.leechers_connected_to) +- { +- to_update.append(model->index(row, LEECHERS)); +- leechers_total = s.leechers_total; +- leechers_connected_to = s.leechers_connected_to; +- if (sort_column == LEECHERS) +- ret = true; +- } +- +- double perc = Percentage(s); +- if (fabs(percentage - perc) > 0.001) +- { +- to_update.append(model->index(row, PERCENTAGE)); +- percentage = perc; +- if (sort_column == PERCENTAGE) +- ret = true; +- } +- +- float ratio = s.shareRatio(); +- if (fabsf(share_ratio - ratio) > 0.001) +- { +- to_update.append(model->index(row, SHARE_RATIO)); +- share_ratio = ratio; +- if (sort_column == SHARE_RATIO) +- ret = true; +- } ++ const auto update_if_differs = [&](auto &target, const auto &source, int column){ ++ if (target != source) { ++ to_update.append(model->index(row, column)); ++ target = source; ++ ret |= (sort_column == column); ++ } ++ }; + +- Uint32 rdl = tc->getRunningTimeDL(); +- if (runtime_dl != rdl) +- { +- to_update.append(model->index(row, DOWNLOAD_TIME)); +- runtime_dl = rdl; +- if (sort_column == DOWNLOAD_TIME) +- ret = true; +- } ++ const auto update_if_differs_float = [&](auto &target, const auto &source, int column){ ++ if (fabs(target - source) > 0.001) { ++ to_update.append(model->index(row, column)); ++ target = source; ++ ret |= (sort_column == column); ++ } ++ }; ++ ++ update_if_differs(status, s.status, NAME); ++ update_if_differs(bytes_downloaded, s.bytes_downloaded, BYTES_DOWNLOADED); ++ update_if_differs(total_bytes_to_download, s.total_bytes_to_download, TOTAL_BYTES_TO_DOWNLOAD); ++ update_if_differs(bytes_uploaded, s.bytes_uploaded, BYTES_UPLOADED); ++ update_if_differs(bytes_left, s.bytes_left, BYTES_LEFT); ++ update_if_differs(download_rate, s.download_rate, DOWNLOAD_RATE); ++ update_if_differs(upload_rate, s.upload_rate, UPLOAD_RATE); ++ update_if_differs(eta, tc->getETA(), ETA); ++ update_if_differs(seeders_connected_to, s.seeders_connected_to, SEEDERS); ++ update_if_differs(seeders_total, s.seeders_total, SEEDERS); ++ update_if_differs(leechers_connected_to, s.leechers_connected_to, LEECHERS); ++ update_if_differs(leechers_total, s.leechers_total, LEECHERS); ++ ++ update_if_differs_float(percentage, Percentage(s), PERCENTAGE); ++ update_if_differs_float(share_ratio, s.shareRatio(), SHARE_RATIO); ++ ++ update_if_differs(runtime_dl, tc->getRunningTimeDL(), DOWNLOAD_TIME); ++ const auto rul = (tc->getRunningTimeUL() >= tc->getRunningTimeDL() ++ ? tc->getRunningTimeUL() - tc->getRunningTimeDL() ++ : 0); ++ update_if_differs(runtime_ul, rul, SEED_TIME); + +- Uint32 rul = tc->getRunningTimeUL(); +- rul = rul >= rdl ? rul - rdl : 0; // make sure rul cannot go negative +- if (runtime_ul != rul) +- { +- to_update.append(model->index(row, SEED_TIME)); +- runtime_ul = rul; +- if (sort_column == SEED_TIME) +- ret = true; +- } + return ret; + } + +@@ -223,13 +142,11 @@ namespace kt + return BytesPerSecToString(download_rate); + else + return QVariant(); +- break; + case UPLOAD_RATE: + if (upload_rate >= 103) // lowest "visible" speed, all below will be 0,0 Kb/s + return BytesPerSecToString(upload_rate); + else + return QVariant(); +- break; + case ETA: + if (eta == bt::TimeEstimator::NEVER) + return QString(QChar(0x221E)); // infinity +@@ -237,7 +154,6 @@ namespace kt + return DurationToString(eta); + else + return QVariant(); +- break; + case SEEDERS: + return QString(QString::number(seeders_connected_to) + QLatin1String(" (") + QString::number(seeders_total) + QLatin1Char(')')); + case LEECHERS: +@@ -397,7 +313,7 @@ namespace kt + connect(core, &Core::torrentRemoved, this, &ViewModel::removeTorrent); + sort_column = 0; + sort_order = Qt::AscendingOrder; +- group = 0; ++ group = nullptr; + num_visible = 0; + + kt::QueueManager* qman = core->getQueueManager(); +@@ -635,7 +551,7 @@ namespace kt + if (!index.isValid() || index.row() >= torrents.count()) + return QVariant(); + +- Item* item = (Item*)index.internalPointer(); ++ Item* item = reinterpret_cast(index.internalPointer()); + if (!item) + return QVariant(); + +@@ -699,7 +615,7 @@ namespace kt + return false; + + QString name = value.toString(); +- Item* item = (Item*)index.internalPointer(); ++ Item* item = reinterpret_cast(index.internalPointer()); + if (!item) + return false; + +@@ -796,28 +712,20 @@ namespace kt + } + } + +- const bt::TorrentInterface* ViewModel::torrentFromIndex(const QModelIndex& index) const +- { +- if (index.isValid() && index.row() < torrents.count()) +- return torrents[index.row()]->tc; +- else +- return 0; +- } +- +- bt::TorrentInterface* ViewModel::torrentFromIndex(const QModelIndex& index) ++ bt::TorrentInterface* ViewModel::torrentFromIndex(const QModelIndex& index) const + { + if (index.isValid() && index.row() < torrents.count()) + return torrents[index.row()]->tc; + else +- return 0; ++ return nullptr; + } + +- bt::TorrentInterface* ViewModel::torrentFromRow(int index) ++ bt::TorrentInterface* ViewModel::torrentFromRow(int index) const + { + if (index < torrents.count() && index >= 0) + return torrents[index]->tc; + else +- return 0; ++ return nullptr; + } + + void ViewModel::allTorrents(QList & tlist) const +@@ -854,10 +762,7 @@ namespace kt + void ViewModel::onExit() + { + // items should be removed before Core delete their tc data. +- for (Item* item : qAsConst(torrents)) +- { +- removeTorrent(item->tc); +- } ++ removeRows(0, rowCount(), QModelIndex()); + } + + class ViewModelItemCmp +diff --git a/ktorrent/view/viewmodel.h b/ktorrent/view/viewmodel.h +index d4e0a64..6422396 100644 +--- a/ktorrent/view/viewmodel.h ++++ b/ktorrent/view/viewmodel.h +@@ -22,9 +22,15 @@ + #ifndef KTVIEWMODEL_H + #define KTVIEWMODEL_H + +-#include + #include +-#include ++#include ++ ++#include ++#include ++ ++namespace bt { ++ class TorrentInterface; ++} + + namespace kt + { +@@ -98,21 +104,14 @@ namespace kt + * @param index The model index + * @return The torrent if the index is valid and in the proper range, 0 otherwise + */ +- const bt::TorrentInterface* torrentFromIndex(const QModelIndex& index) const; +- +- /** +- * Get a torrent from a model index. +- * @param index The model index +- * @return The torrent if the index is valid and in the proper range, 0 otherwise +- */ +- bt::TorrentInterface* torrentFromIndex(const QModelIndex& index); ++ bt::TorrentInterface *torrentFromIndex(const QModelIndex& index) const; + + /** + * Get a torrent from a row. + * @param index The row index + * @return The torrent if the index is valid and in the proper range, 0 otherwise + */ +- bt::TorrentInterface* torrentFromRow(int index); ++ bt::TorrentInterface* torrentFromRow(int index) const; + + /** + * Get all torrents +-- +cgit v1.1 diff --git a/net-p2p/ktorrent/ktorrent-5.1.2-r2.ebuild b/net-p2p/ktorrent/ktorrent-5.1.2-r2.ebuild new file mode 100644 index 00000000000..a23633e653d --- /dev/null +++ b/net-p2p/ktorrent/ktorrent-5.1.2-r2.ebuild @@ -0,0 +1,106 @@ +# Copyright 1999-2019 Gentoo Authors +# Distributed under the terms of the GNU General Public License v2 + +EAPI=7 + +KDE_HANDBOOK="optional" +KDE_TEST="optional" +VIRTUALX_REQUIRED="test" +inherit kde5 + +DESCRIPTION="Powerful BitTorrent client based on KDE Frameworks" +HOMEPAGE="https://kde.org/applications/internet/ktorrent/" +[[ ${KDE_BUILD_TYPE} = release ]] && SRC_URI="mirror://kde/stable/${PN}/${PV/%.0}/${P}.tar.xz" + +LICENSE="GPL-2" +KEYWORDS="~amd64 ~arm64 ~x86" +IUSE="+bwscheduler +downloadorder +infowidget +ipfilter +kross +logviewer +magnetgenerator ++mediaplayer rss +scanfolder +search +shutdown +stats +upnp +zeroconf" + +BDEPEND="sys-devel/gettext" +COMMON_DEPEND=" + $(add_frameworks_dep kcmutils) + $(add_frameworks_dep kconfig) + $(add_frameworks_dep kconfigwidgets) + $(add_frameworks_dep kcoreaddons) + $(add_frameworks_dep kcrash) + $(add_frameworks_dep kdbusaddons) + $(add_frameworks_dep ki18n) + $(add_frameworks_dep kiconthemes) + $(add_frameworks_dep kio) + $(add_frameworks_dep knotifications) + $(add_frameworks_dep knotifyconfig) + $(add_frameworks_dep kparts) + $(add_frameworks_dep kwidgetsaddons) + $(add_frameworks_dep kwindowsystem) + $(add_frameworks_dep kxmlgui) + $(add_frameworks_dep solid) + $(add_qt_dep qtdbus) + $(add_qt_dep qtgui) + $(add_qt_dep qtnetwork) + $(add_qt_dep qtwidgets) + $(add_qt_dep qtxml) + >=net-libs/libktorrent-2.1.1:5 + infowidget? ( dev-libs/geoip ) + kross? ( + $(add_frameworks_dep karchive) + $(add_frameworks_dep kitemviews) + $(add_frameworks_dep kross) + ) + mediaplayer? ( + media-libs/phonon[qt5(+)] + >=media-libs/taglib-1.5 + ) + rss? ( + $(add_frameworks_dep kdewebkit) + $(add_frameworks_dep syndication) + ) + search? ( + $(add_frameworks_dep kdewebkit) + >=dev-qt/qtwebkit-5.212.0_pre20180120:5 + ) + shutdown? ( $(add_plasma_dep plasma-workspace) ) + stats? ( $(add_frameworks_dep kplotting) ) + upnp? ( $(add_frameworks_dep kcompletion) ) + zeroconf? ( $(add_frameworks_dep kdnssd) ) +" +DEPEND="${COMMON_DEPEND} + dev-libs/boost +" +RDEPEND="${COMMON_DEPEND} + ipfilter? ( + app-arch/bzip2 + app-arch/unzip + $(add_frameworks_dep ktextwidgets) + $(add_kdeapps_dep kio-extras) + ) +" + +PATCHES=( + "${FILESDIR}/${PN}-5.1.1-singlefile-torrent.patch" # git master + "${FILESDIR}/${P}-crash-on-exit.patch" # bug #632588 +) + +src_configure() { + local mycmakeargs=( + -DENABLE_BWSCHEDULER_PLUGIN=$(usex bwscheduler) + -DENABLE_DOWNLOADORDER_PLUGIN=$(usex downloadorder) + -DENABLE_INFOWIDGET_PLUGIN=$(usex infowidget) + -DWITH_SYSTEM_GEOIP=$(usex infowidget) + -DENABLE_IPFILTER_PLUGIN=$(usex ipfilter) + -DENABLE_SCRIPTING_PLUGIN=$(usex kross) + -DENABLE_LOGVIEWER_PLUGIN=$(usex logviewer) + -DENABLE_MAGNETGENERATOR_PLUGIN=$(usex magnetgenerator) + -DENABLE_MEDIAPLAYER_PLUGIN=$(usex mediaplayer) + $(cmake-utils_use_find_package rss KF5Syndication) + -DENABLE_SCANFOLDER_PLUGIN=$(usex scanfolder) + -DENABLE_SEARCH_PLUGIN=$(usex search) + -DENABLE_SHUTDOWN_PLUGIN=$(usex shutdown) + -DENABLE_STATS_PLUGIN=$(usex stats) + -DENABLE_UPNP_PLUGIN=$(usex upnp) + -DENABLE_ZEROCONF_PLUGIN=$(usex zeroconf) + ) +# add back when ported +# -DENABLE_WEBINTERFACE_PLUGIN=$(usex webinterface) + kde5_src_configure +}