From e120536d8766d07c0ec27accc08a01224e8de1e3 Mon Sep 17 00:00:00 2001 From: Calum Lind Date: Fri, 8 Jul 2022 08:29:18 +0100 Subject: [PATCH] Fix parsing magnet with tracker tiers Magnets with trackers specified with tr.x param were not being unquoted so unusable raw tracker string was being set. Fixed by unquoting tracker and adding test See-also: https://dev.deluge-torrent.org/ticket/2716 --- deluge/common.py | 18 ++++++++++-------- deluge/tests/test_common.py | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/deluge/common.py b/deluge/common.py index 77573ffd7..ecf90a390 100644 --- a/deluge/common.py +++ b/deluge/common.py @@ -734,6 +734,8 @@ MAGNET_SCHEME = 'magnet:?' XT_BTIH_PARAM = 'xt=urn:btih:' DN_PARAM = 'dn=' TR_PARAM = 'tr=' +TR_TIER_PARAM = 'tr.' +TR_TIER_REGEX = re.compile(r'^tr.(\d+)=(\S+)') def is_magnet(uri): @@ -776,8 +778,6 @@ def get_magnet_info(uri): """ - tr0_param = 'tr.' - tr0_param_regex = re.compile(r'^tr.(\d+)=(\S+)') if not uri.startswith(MAGNET_SCHEME): return {} @@ -805,12 +805,14 @@ def get_magnet_info(uri): tracker = unquote_plus(param[len(TR_PARAM) :]) trackers[tracker] = tier tier += 1 - elif param.startswith(tr0_param): - try: - tier, tracker = re.match(tr0_param_regex, param).groups() - trackers[tracker] = tier - except AttributeError: - pass + elif param.startswith(TR_TIER_PARAM): + tracker_match = re.match(TR_TIER_REGEX, param) + if not tracker_match: + continue + + tier, tracker = tracker_match.groups() + tracker = unquote_plus(tracker) + trackers[tracker] = int(tier) if info_hash: if not name: diff --git a/deluge/tests/test_common.py b/deluge/tests/test_common.py index e5027ebca..780d368ef 100644 --- a/deluge/tests/test_common.py +++ b/deluge/tests/test_common.py @@ -7,6 +7,7 @@ import os import sys import tarfile +from urllib.parse import quote_plus import pytest @@ -19,6 +20,7 @@ from deluge.common import ( fsize, fspeed, ftime, + get_magnet_info, get_path_size, is_infohash, is_interface, @@ -209,3 +211,16 @@ class TestCommon: if tar_info.name == 'archive_message.txt': result = tar.extractfile(tar_info).read().decode() assert result == 'test' + + def test_get_magnet_info_tiers(self): + tracker1 = 'udp://tracker1.example.com' + tracker2 = 'udp://tracker2.example.com' + magnet = ( + 'magnet:?xt=urn:btih:SU5225URMTUEQLDXQWRB2EQWN6KLTYKN' + f'&tr.1={quote_plus(tracker1)}' + f'&tr.2={quote_plus(tracker2)}' + ) + result = get_magnet_info(magnet) + assert result['info_hash'] == '953bad769164e8482c7785a21d12166f94b9e14d' + assert result['trackers'][tracker1] == 1 + assert result['trackers'][tracker2] == 2