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
This commit is contained in:
Calum Lind 2022-07-08 08:29:18 +01:00
parent f52cf760e4
commit e120536d87
No known key found for this signature in database
GPG Key ID: 90597A687B836BA3
2 changed files with 25 additions and 8 deletions

View File

@ -734,6 +734,8 @@ MAGNET_SCHEME = 'magnet:?'
XT_BTIH_PARAM = 'xt=urn:btih:' XT_BTIH_PARAM = 'xt=urn:btih:'
DN_PARAM = 'dn=' DN_PARAM = 'dn='
TR_PARAM = 'tr=' TR_PARAM = 'tr='
TR_TIER_PARAM = 'tr.'
TR_TIER_REGEX = re.compile(r'^tr.(\d+)=(\S+)')
def is_magnet(uri): 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): if not uri.startswith(MAGNET_SCHEME):
return {} return {}
@ -805,12 +805,14 @@ def get_magnet_info(uri):
tracker = unquote_plus(param[len(TR_PARAM) :]) tracker = unquote_plus(param[len(TR_PARAM) :])
trackers[tracker] = tier trackers[tracker] = tier
tier += 1 tier += 1
elif param.startswith(tr0_param): elif param.startswith(TR_TIER_PARAM):
try: tracker_match = re.match(TR_TIER_REGEX, param)
tier, tracker = re.match(tr0_param_regex, param).groups() if not tracker_match:
trackers[tracker] = tier continue
except AttributeError:
pass tier, tracker = tracker_match.groups()
tracker = unquote_plus(tracker)
trackers[tracker] = int(tier)
if info_hash: if info_hash:
if not name: if not name:

View File

@ -7,6 +7,7 @@
import os import os
import sys import sys
import tarfile import tarfile
from urllib.parse import quote_plus
import pytest import pytest
@ -19,6 +20,7 @@ from deluge.common import (
fsize, fsize,
fspeed, fspeed,
ftime, ftime,
get_magnet_info,
get_path_size, get_path_size,
is_infohash, is_infohash,
is_interface, is_interface,
@ -209,3 +211,16 @@ class TestCommon:
if tar_info.name == 'archive_message.txt': if tar_info.name == 'archive_message.txt':
result = tar.extractfile(tar_info).read().decode() result = tar.extractfile(tar_info).read().decode()
assert result == 'test' 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