Skip to content

Commit 31d4726

Browse files
Filter unsupported tracker URLs from magnets
1 parent 8cded3c commit 31d4726

3 files changed

Lines changed: 110 additions & 0 deletions

File tree

src/base/bittorrent/torrentdescriptor.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828

2929
#include "torrentdescriptor.h"
3030

31+
#include <utility>
32+
#include <vector>
33+
3134
#include <libtorrent/load_torrent.hpp>
3235
#include <libtorrent/magnet_uri.hpp>
3336
#include <libtorrent/torrent_info.hpp>
@@ -84,6 +87,40 @@ namespace
8487

8588
return limits;
8689
}
90+
91+
bool isSupportedTrackerURL(const QString &url)
92+
{
93+
const QUrl trackerURL {url};
94+
if (!trackerURL.isValid() || trackerURL.host().isEmpty())
95+
return false;
96+
97+
const QString scheme = trackerURL.scheme();
98+
return ((scheme == u"http") || (scheme == u"https") || (scheme == u"udp"));
99+
}
100+
101+
void removeUnsupportedTrackers(lt::add_torrent_params &params)
102+
{
103+
if (params.trackers.empty())
104+
return;
105+
106+
std::vector<std::string> trackers;
107+
std::vector<int> trackerTiers;
108+
trackers.reserve(params.trackers.size());
109+
trackerTiers.reserve(params.trackers.size());
110+
111+
for (std::size_t i = 0; i < params.trackers.size(); ++i)
112+
{
113+
const QString tracker = QString::fromStdString(params.trackers[i]);
114+
if (!isSupportedTrackerURL(tracker))
115+
continue;
116+
117+
trackers.push_back(params.trackers[i]);
118+
trackerTiers.push_back((i < params.tracker_tiers.size()) ? params.tracker_tiers[i] : 0);
119+
}
120+
121+
params.trackers = std::move(trackers);
122+
params.tracker_tiers = std::move(trackerTiers);
123+
}
87124
}
88125

89126
const int TORRENTDESCRIPTOR_TYPEID = qRegisterMetaType<BitTorrent::TorrentDescriptor>();
@@ -161,6 +198,8 @@ catch (const lt::system_error &err)
161198
BitTorrent::TorrentDescriptor::TorrentDescriptor(lt::add_torrent_params ltAddTorrentParams)
162199
: m_ltAddTorrentParams {std::move(ltAddTorrentParams)}
163200
{
201+
removeUnsupportedTrackers(m_ltAddTorrentParams);
202+
164203
if (m_ltAddTorrentParams.ti && m_ltAddTorrentParams.ti->is_valid())
165204
{
166205
m_info.emplace(*m_ltAddTorrentParams.ti);

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ include_directories("../src")
88
set(testFiles
99
testalgorithm.cpp
1010
testbittorrentpeeraddress.cpp
11+
testbittorrenttorrentdescriptor.cpp
1112
testbittorrenttrackerentry.cpp
1213
testconceptsexplicitlyconvertibleto.cpp
1314
testconceptsstringable.cpp
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Bittorrent Client using Qt and libtorrent.
3+
* Copyright (C) 2026 Andy Ye
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU General Public License
7+
* as published by the Free Software Foundation; either version 2
8+
* of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
*
19+
* In addition, as a special exception, the copyright holders give permission to
20+
* link this program with the OpenSSL project's "OpenSSL" library (or with
21+
* modified versions of it that use the same license as the "OpenSSL" library),
22+
* and distribute the linked executables. You must obey the GNU General Public
23+
* License in all respects for all of the code used other than "OpenSSL". If you
24+
* modify file(s), you may extend this exception to your version of the file(s),
25+
* but you are not obligated to do so. If you do not wish to do so, delete this
26+
* exception statement from your version.
27+
*/
28+
29+
#include <QObject>
30+
#include <QTest>
31+
32+
#include "base/bittorrent/torrentdescriptor.h"
33+
#include "base/bittorrent/trackerentry.h"
34+
#include "base/global.h"
35+
36+
class TestBittorrentTorrentDescriptor final : public QObject
37+
{
38+
Q_OBJECT
39+
Q_DISABLE_COPY_MOVE(TestBittorrentTorrentDescriptor)
40+
41+
public:
42+
TestBittorrentTorrentDescriptor() = default;
43+
44+
private slots:
45+
void testParseMagnetFiltersUnsupportedTrackers() const
46+
{
47+
const QString magnet =
48+
u"magnet:?xt=urn:btih:c58645e2e922428dceb1f98f51ffa424810570f0"
49+
"&tr=http%3A%2F%2Ftracker.example.com%2Fannounce"
50+
"&tr=udp%3A%2F%2Ftracker.example.com%3A1337%2Fannounce"
51+
"&tr=%3C!DOCTYPE%20html%3E%3Chtml%3E"
52+
"&tr=ftp%3A%2F%2Ftracker.example.com%2Fannounce"
53+
"&tr=313131"_s;
54+
55+
const auto parseResult = BitTorrent::TorrentDescriptor::parse(magnet);
56+
QVERIFY(parseResult);
57+
58+
const QList<BitTorrent::TrackerEntry> trackers = parseResult.value().trackers();
59+
QCOMPARE(trackers.size(), 2);
60+
QCOMPARE(trackers.at(0).url, u"http://tracker.example.com/announce"_s);
61+
QCOMPARE(trackers.at(1).url, u"udp://tracker.example.com:1337/announce"_s);
62+
63+
const lt::add_torrent_params &nativeParams = parseResult.value().ltAddTorrentParams();
64+
QCOMPARE(nativeParams.trackers.size(), 2);
65+
QCOMPARE(nativeParams.tracker_tiers.size(), 2);
66+
}
67+
};
68+
69+
QTEST_APPLESS_MAIN(TestBittorrentTorrentDescriptor)
70+
#include "testbittorrenttorrentdescriptor.moc"

0 commit comments

Comments
 (0)