Merge ~cjwatson/txpkgupload:py3-sftp-paths into txpkgupload:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 682481de9d1782982d78f58cbf29d0cd802b589e
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/txpkgupload:py3-sftp-paths
Merge into: txpkgupload:master
Diff against target: 43 lines (+16/-1)
2 files modified
src/txpkgupload/filesystem.py (+13/-0)
src/txpkgupload/tests/test_twistedsftp.py (+3/-1)
Reviewer Review Type Date Requested Status
Ioana Lasc (community) Approve
Review via email: mp+392996@code.launchpad.net

Commit message

Handle FTP/SFTP path type mismatch in UploadFileSystem

Description of the change

zope.server's FTP implementation passes paths as text, while Twisted's SFTP implementation passes paths as bytes. Resolve this mismatch in a semi-reasonable way.

To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/txpkgupload/filesystem.py b/src/txpkgupload/filesystem.py
2index eccf4b7..b80837f 100644
3--- a/src/txpkgupload/filesystem.py
4+++ b/src/txpkgupload/filesystem.py
5@@ -29,6 +29,19 @@ class UploadFileSystem:
6 return full_path
7
8 def _sanitize(self, path):
9+ if isinstance(path, bytes):
10+ # zope.server's FTP implementation seems to decode all commands
11+ # (including the paths they contain) to text using UTF-8,
12+ # effectively assuming the recommendation in RFC 2640 except
13+ # without the feature negotiation part. However, Twisted's SFTP
14+ # implementation leaves paths as bytes. Since in practice
15+ # legitimate uses of txpkgupload will only involve ASCII paths,
16+ # and since UTF-8 has low risk of undetected decoding errors,
17+ # let's try to decode SFTP paths as UTF-8.
18+ try:
19+ path = path.decode('UTF-8')
20+ except UnicodeDecodeError:
21+ raise NotImplementedError('Paths must be encoded using UTF-8')
22 if path.startswith('/'):
23 path = path[1:]
24 path = os.path.normpath(path)
25diff --git a/src/txpkgupload/tests/test_twistedsftp.py b/src/txpkgupload/tests/test_twistedsftp.py
26index 3ddeeb0..01b5e20 100644
27--- a/src/txpkgupload/tests/test_twistedsftp.py
28+++ b/src/txpkgupload/tests/test_twistedsftp.py
29@@ -9,6 +9,7 @@ import os
30
31 import fixtures
32 from lazr.sshserver.sftp import FileIsADirectory
33+import six
34 import testtools
35
36 from txpkgupload.twistedsftp import SFTPServer
37@@ -73,4 +74,5 @@ class TestSFTPServer(testtools.TestCase):
38 upload_file = self.sftp_server.openFile('bar/foo', None, None)
39 err = self.assertRaises(
40 FileIsADirectory, upload_file.writeChunk, 0, b"This is a test")
41- self.assertEqual("File is a directory: '%s'" % dir_name, str(err))
42+ self.assertEqual(
43+ "File is a directory: %r" % six.ensure_text(dir_name), str(err))

Subscribers

People subscribed via source and target branches

to all changes: