Skip to content

Commit f5a7935

Browse files
bbaylesmerwok
authored andcommitted
bpo-32304: Fix distutils upload for tar files ending with b'\r' (GH-5264) (GH-5331)
Patch by Bo Bayles.
1 parent 5679277 commit f5a7935

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

Doc/whatsnew/2.7.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,11 @@ changes, or look through the Subversion logs for all the details.
12181218
created some new files that should be included.
12191219
(Fixed by Tarek Ziadé; :issue:`8688`.)
12201220

1221+
The ``upload`` command now longer tries to change CR end-of-line characters
1222+
to CRLF. This fixes a corruption issue with sdists that ended with a byte
1223+
equivalent to CR.
1224+
(Contributed by Bo Bayles in :issue:`32304`.)
1225+
12211226
* The :mod:`doctest` module's :const:`IGNORE_EXCEPTION_DETAIL` flag
12221227
will now ignore the name of the module containing the exception
12231228
being tested. (Patch by Lennart Regebro; :issue:`7490`.)

Lib/distutils/command/upload.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,6 @@ def upload_file(self, command, pyversion, filename):
155155
body.write(fn)
156156
body.write("\r\n\r\n")
157157
body.write(value)
158-
if value and value[-1] == '\r':
159-
body.write('\n') # write an extra newline (lurve Macs)
160158
body.write(end_boundary)
161159
body = body.getvalue()
162160

Lib/distutils/tests/test_upload.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,32 @@ def test_upload(self):
128128
auth = self.last_open.req.headers['Authorization']
129129
self.assertNotIn('\n', auth)
130130

131+
# bpo-32304: archives whose last byte was b'\r' were corrupted due to
132+
# normalization intended for Mac OS 9.
133+
def test_upload_correct_cr(self):
134+
# content that ends with \r should not be modified.
135+
tmp = self.mkdtemp()
136+
path = os.path.join(tmp, 'xxx')
137+
self.write_file(path, content='yy\r')
138+
command, pyversion, filename = 'xxx', '2.6', path
139+
dist_files = [(command, pyversion, filename)]
140+
self.write_file(self.rc, PYPIRC_LONG_PASSWORD)
141+
142+
# other fields that ended with \r used to be modified, now are
143+
# preserved.
144+
pkg_dir, dist = self.create_dist(
145+
dist_files=dist_files,
146+
description='long description\r'
147+
)
148+
cmd = upload(dist)
149+
cmd.ensure_finalized()
150+
cmd.run()
151+
152+
headers = dict(self.last_open.req.headers)
153+
self.assertEqual(headers['Content-length'], '2170')
154+
self.assertIn(b'long description\r', self.last_open.req.data)
155+
self.assertNotIn(b'long description\r\n', self.last_open.req.data)
156+
131157
def test_upload_fails(self):
132158
self.next_msg = "Not Found"
133159
self.next_code = 404
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
distutils' upload command no longer corrupts tar files ending with a CR byte,
2+
and no longer tries to convert CR to CRLF in any of the upload text fields.

0 commit comments

Comments
 (0)