Skip to content

Commit

Permalink
Merge pull request #7551 from xoriole/fix/create-torrent
Browse files Browse the repository at this point in the history
Fix creating torrent with name containing escape characters
  • Loading branch information
xoriole authored Aug 17, 2023
2 parents 080f23d + a3eb6aa commit b7cfa8a
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 5 deletions.
31 changes: 30 additions & 1 deletion src/tribler/gui/dialogs/createtorrentdialog.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import os
import re
import typing

from PyQt5 import uic
from PyQt5.QtCore import QDir, pyqtSignal
from PyQt5.QtGui import QValidator
from PyQt5.QtWidgets import QAction, QFileDialog, QSizePolicy, QTreeWidgetItem

from tribler.gui.defs import BUTTON_TYPE_NORMAL
Expand All @@ -17,6 +20,29 @@ def __init__(self, parent):
QTreeWidgetItem.__init__(self, parent)


class TorrentNameValidator(QValidator):
"""
Validator used in Torrent name QLineEdit field to disallow multiline text.
If a new line character is detected, then it is converted to space using fixup().
Docs: https://doc.qt.io/qtforpython-5/PySide2/QtGui/QValidator.html
"""
ESCAPE_CHARS_REGEX = r'[\n\r\t]'

def validate(self, text: str, pos: int) -> typing.Tuple['QValidator.State', str, int]:
if re.search(self.ESCAPE_CHARS_REGEX, text):
return QValidator.Intermediate, text, pos
return QValidator.Acceptable, text, pos

def fixup(self, text: str) -> str:
return re.sub(self.ESCAPE_CHARS_REGEX, ' ', text)


def sanitize_filename(filename: str) -> str:
"""Removes some selected escape characters from the filename and returns the cleaned value."""
return re.sub(r'[\n\r\t]', '', filename)


class CreateTorrentDialog(DialogContainer):
create_torrent_notification = pyqtSignal(dict)
add_to_channel_selected = pyqtSignal(str)
Expand All @@ -27,6 +53,7 @@ def __init__(self, parent):
uic.loadUi(get_ui_file_path('createtorrentdialog.ui'), self.dialog_widget)

self.dialog_widget.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)
self.dialog_widget.create_torrent_name_field.setValidator(TorrentNameValidator(parent=self))
connect(self.dialog_widget.btn_cancel.clicked, self.close_dialog)
connect(self.dialog_widget.create_torrent_choose_files_button.clicked, self.on_choose_files_clicked)
connect(self.dialog_widget.create_torrent_choose_dir_button.clicked, self.on_choose_dir_clicked)
Expand Down Expand Up @@ -109,7 +136,9 @@ def on_create_clicked(self, checked):
)
return

self.name = self.dialog_widget.create_torrent_name_field.text()
torrent_name = self.dialog_widget.create_torrent_name_field.text()
self.name = sanitize_filename(torrent_name)

description = self.dialog_widget.create_torrent_description_field.toPlainText()

is_seed = self.dialog_widget.seed_after_adding_checkbox.isChecked()
Expand Down
Empty file.
31 changes: 31 additions & 0 deletions src/tribler/gui/dialogs/tests/test_createtorrentdialog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from PyQt5.QtGui import QValidator

from tribler.gui.dialogs.createtorrentdialog import sanitize_filename, TorrentNameValidator


def test_torrent_name_validator():
"""
Tests if the torrent name validator marks the input as valid if there are no multiline characters.
Upon fixup, the invalid characters are accepted correctly.
"""
def assert_text_is_valid(validator: QValidator, original_text: str, expected_to_be_valid: bool):
state, text, pos = validator.validate(original_text, len(original_text))
assert state == QValidator.Acceptable if expected_to_be_valid else QValidator.Intermediate
assert text == original_text
assert pos == len(original_text)

validator = TorrentNameValidator(None)

invalid_name = """line 1
line2.torrent
"""
assert_text_is_valid(validator, invalid_name, expected_to_be_valid=False)

fixed_name = validator.fixup(invalid_name)
assert_text_is_valid(validator, fixed_name, expected_to_be_valid=True)


def test_sanitize_filename():
original_filename = "This \nIs \r\nA \tTorrent Name.torrent"
expected_sanitized_filename = "This Is A Torrent Name.torrent"
assert sanitize_filename(original_filename) == expected_sanitized_filename
6 changes: 2 additions & 4 deletions src/tribler/gui/tests/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
import pytest

from tribler.gui.utilities import TranslatedString, compose_magnetlink, create_api_key, dict_item_is_any_of, \
duration_to_string, \
format_api_key, \
quote_plus_unicode, set_api_key, unicode_quoter, get_i18n_file_path, I18N_DIR, LANGUAGES_FILE, \
get_languages_file_content
duration_to_string, format_api_key, get_i18n_file_path, get_languages_file_content, I18N_DIR, LANGUAGES_FILE, \
quote_plus_unicode, set_api_key, unicode_quoter


def test_quoter_char():
Expand Down

0 comments on commit b7cfa8a

Please sign in to comment.