[Core] Fix potential renaming unicode folders issue

- Found an issue while fixing `get_name` where `handle.rename_file`
  would raise a UnicodeDecodeError with non-ascii on Python 2. The
  fix is to catch this and pass unicode string to method instead.

- Add a test `test_rename_unicode` to verify no errors are generated.
- Updated test to use core.session instead of creating another one.
This commit is contained in:
Calum Lind 2018-10-22 14:38:47 +01:00
commit e6c61c3f8c
2 changed files with 19 additions and 5 deletions

View file

@ -1382,7 +1382,7 @@ class Torrent(object):
# lt needs utf8 byte-string. Otherwise if wstrings enabled, unicode string. # lt needs utf8 byte-string. Otherwise if wstrings enabled, unicode string.
try: try:
self.handle.rename_file(index, filename.encode('utf8')) self.handle.rename_file(index, filename.encode('utf8'))
except TypeError: except (UnicodeDecodeError, TypeError):
self.handle.rename_file(index, filename) self.handle.rename_file(index, filename)
def rename_folder(self, folder, new_folder): def rename_folder(self, folder, new_folder):
@ -1418,7 +1418,7 @@ class Torrent(object):
new_path = _file['path'].replace(folder, new_folder, 1) new_path = _file['path'].replace(folder, new_folder, 1)
try: try:
self.handle.rename_file(_file['index'], new_path.encode('utf8')) self.handle.rename_file(_file['index'], new_path.encode('utf8'))
except TypeError: except (UnicodeDecodeError, TypeError):
self.handle.rename_file(_file['index'], new_path) self.handle.rename_file(_file['index'], new_path)
def on_folder_rename_complete(dummy_result, torrent, folder, new_folder): def on_folder_rename_complete(dummy_result, torrent, folder, new_folder):

View file

@ -13,7 +13,7 @@ from base64 import b64encode
import mock import mock
from twisted.internet import reactor from twisted.internet import reactor
from twisted.internet.task import deferLater from twisted.internet.task import defer, deferLater
from twisted.trial import unittest from twisted.trial import unittest
import deluge.component as component import deluge.component as component
@ -24,7 +24,7 @@ from deluge.common import utf8_encode_structure, windows_check
from deluge.core.core import Core from deluge.core.core import Core
from deluge.core.rpcserver import RPCServer from deluge.core.rpcserver import RPCServer
from deluge.core.torrent import Torrent from deluge.core.torrent import Torrent
from deluge.core.torrentmanager import TorrentState from deluge.core.torrentmanager import TorrentManager, TorrentState
from .basetest import BaseTestCase from .basetest import BaseTestCase
@ -44,7 +44,7 @@ class TorrentTestCase(BaseTestCase):
self.rpcserver = RPCServer(listen=False) self.rpcserver = RPCServer(listen=False)
self.core = Core() self.core = Core()
self.core.config.config['lsd'] = False self.core.config.config['lsd'] = False
self.session = lt.session() self.session = self.core.session
self.torrent = None self.torrent = None
return component.start() return component.start()
@ -304,3 +304,17 @@ class TorrentTestCase(BaseTestCase):
handle = self.session.add_torrent(atp) handle = self.session.add_torrent(atp)
self.torrent = Torrent(handle, {}) self.torrent = Torrent(handle, {})
self.assertEqual(self.torrent.get_name(), 'সুকুমার রায়.mkv') self.assertEqual(self.torrent.get_name(), 'সুকুমার রায়.mkv')
def test_rename_unicode(self):
"""Test renaming file/folders with unicode filenames."""
atp = self.get_torrent_atp('unicode_filenames.torrent')
handle = self.session.add_torrent(atp)
self.torrent = Torrent(handle, {})
# Ignore TorrentManager method call
TorrentManager.save_resume_data = mock.MagicMock
result = self.torrent.rename_folder('unicode_filenames', 'Горбачёв')
self.assertIsInstance(result, defer.DeferredList)
result = self.torrent.rename_files([[0, 'new_рбачёв']])
self.assertIsNone(result)