summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCalum Lind <calumlind+deluge@gmail.com>2020-04-25 12:44:04 +0100
committerCalum Lind <calumlind+deluge@gmail.com>2020-04-25 13:16:04 +0100
commit62d8749e7404f247494fd091f8a17a1c58735606 (patch)
treee435e68a7355fac7ac96ed3186ea6214d3ca714d
parent76f0bf2e04b1b6b58008fb65fa64c8c434aece95 (diff)
downloaddeluge-62d8749e7404f247494fd091f8a17a1c58735606.zip
deluge-62d8749e7404f247494fd091f8a17a1c58735606.tar.gz
deluge-62d8749e7404f247494fd091f8a17a1c58735606.tar.bz2
[#3348] Fix TypeError adding peers to torrents
Python3 has stricter type checking and passing a port as string results in libtorrent raising a TypeError. Fixed by casting port to int, along with refactoring to ensure ipv6 is correctly parsing and a useful error is output to user with invalid ip or port details. https://dev.deluge-torrent.org/ticket/3348
-rw-r--r--deluge/core/torrent.py4
-rw-r--r--deluge/tests/test_torrent.py8
-rw-r--r--deluge/ui/gtk3/common.py29
-rw-r--r--deluge/ui/gtk3/peers_tab.py21
4 files changed, 47 insertions, 15 deletions
diff --git a/deluge/core/torrent.py b/deluge/core/torrent.py
index f40b588..b69909c 100644
--- a/deluge/core/torrent.py
+++ b/deluge/core/torrent.py
@@ -1212,8 +1212,8 @@ class Torrent(object):
bool: True is successful, otherwise False
"""
try:
- self.handle.connect_peer((peer_ip, peer_port), 0)
- except RuntimeError as ex:
+ self.handle.connect_peer((peer_ip, int(peer_port)), 0)
+ except (RuntimeError, ValueError) as ex:
log.debug('Unable to connect to peer: %s', ex)
return False
return True
diff --git a/deluge/tests/test_torrent.py b/deluge/tests/test_torrent.py
index 70fec47..3d47a8a 100644
--- a/deluge/tests/test_torrent.py
+++ b/deluge/tests/test_torrent.py
@@ -345,3 +345,11 @@ class TorrentTestCase(BaseTestCase):
result = self.torrent.rename_files([[0, 'new_рбачёв']])
self.assertIsNone(result)
+
+ def test_connect_peer_port(self):
+ """Test to ensure port is int for libtorrent"""
+ atp = self.get_torrent_atp('test_torrent.file.torrent')
+ handle = self.session.add_torrent(atp)
+ self.torrent = Torrent(handle, {})
+ self.assertFalse(self.torrent.connect_peer('127.0.0.1', 'text'))
+ self.assertTrue(self.torrent.connect_peer('127.0.0.1', '1234'))
diff --git a/deluge/ui/gtk3/common.py b/deluge/ui/gtk3/common.py
index 855f668..0be3bff 100644
--- a/deluge/ui/gtk3/common.py
+++ b/deluge/ui/gtk3/common.py
@@ -29,7 +29,7 @@ from gi.repository.Gtk import (
SortType,
)
-from deluge.common import PY2, get_pixmap, osx_check, windows_check
+from deluge.common import PY2, get_pixmap, is_ip, osx_check, windows_check
log = logging.getLogger(__name__)
@@ -393,3 +393,30 @@ def get_clipboard_text():
def windowing(like):
return like.lower() in str(type(Display.get_default())).lower()
+
+
+def parse_ip_port(text):
+ """Return an IP and port from text.
+
+ Parses both IPv4 and IPv6.
+
+ Params:
+ text (str): Text to be parsed for IP and port.
+
+ Returns:
+ tuple: (ip (str), port (int))
+
+ """
+ if '.' in text:
+ # ipv4
+ ip, __, port = text.rpartition(':')
+ elif '[' in text:
+ # ipv6
+ ip, __, port = text.partition('[')[2].partition(']:')
+ else:
+ return None, None
+
+ if ip and is_ip(ip) and port.isdigit():
+ return ip, int(port)
+ else:
+ return None, None
diff --git a/deluge/ui/gtk3/peers_tab.py b/deluge/ui/gtk3/peers_tab.py
index 33395b9..fa79d84 100644
--- a/deluge/ui/gtk3/peers_tab.py
+++ b/deluge/ui/gtk3/peers_tab.py
@@ -32,6 +32,7 @@ from .common import (
icon_downloading,
icon_seeding,
load_pickled_state_file,
+ parse_ip_port,
save_pickled_state_file,
)
from .torrentdetails import Tab
@@ -376,19 +377,15 @@ class PeersTab(Tab):
peer_dialog = builder.get_object('connect_peer_dialog')
txt_ip = builder.get_object('txt_ip')
response = peer_dialog.run()
+
if response:
value = txt_ip.get_text()
- if value and ':' in value:
- if ']' in value:
- # ipv6
- ip = value.split(']')[0][1:]
- port = value.split(']')[1][1:]
- else:
- # ipv4
- ip = value.split(':')[0]
- port = value.split(':')[1]
- if deluge.common.is_ip(ip):
- log.debug('adding peer %s to %s', value, self.torrent_id)
- client.core.connect_peer(self.torrent_id, ip, port)
+ ip, port = parse_ip_port(value)
+ if ip and port:
+ log.info('Adding peer IP: %s port: %s to %s', ip, port, self.torrent_id)
+ client.core.connect_peer(self.torrent_id, ip, port)
+ else:
+ log.error('Error parsing peer "%s"', value)
+
peer_dialog.destroy()
return True