summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Rollings <1211162+stealthcopter@users.noreply.github.com>2019-12-03 18:18:52 +0000
committerGuido van Rossum <guido@python.org>2019-12-03 10:18:52 -0800
commita016d4e32cc9faa48105d00db275439c3dc93559 (patch)
treedf5b679299d9dabc0ce4fe304ee61ad1190fd112
parent864207181d74800cf3f4e6c45b637854c65aa415 (diff)
downloadcpython-git-a016d4e32cc9faa48105d00db275439c3dc93559.tar.gz
[2.7] bpo-38945: UU Encoding: Don't let newline in filename corrupt the output format (GH-17418). (#17452)
(cherry picked from commit a62ad4730c9b575f140f24074656c0257c86a09a) Co-authored-by: Matthew Rollings <1211162+stealthcopter@users.noreply.github.com>
-rw-r--r--Lib/encodings/uu_codec.py4
-rw-r--r--Lib/test/test_uu.py10
-rwxr-xr-xLib/uu.py7
-rw-r--r--Misc/NEWS.d/next/Security/2019-12-01-22-44-40.bpo-38945.ztmNXc.rst1
4 files changed, 22 insertions, 0 deletions
diff --git a/Lib/encodings/uu_codec.py b/Lib/encodings/uu_codec.py
index 5cb0d2b13e..fcd5aa45a9 100644
--- a/Lib/encodings/uu_codec.py
+++ b/Lib/encodings/uu_codec.py
@@ -31,6 +31,10 @@ def uu_encode(input,errors='strict',filename='<data>',mode=0666):
read = infile.read
write = outfile.write
+ # Remove newline chars from filename
+ filename = filename.replace('\n','\\n')
+ filename = filename.replace('\r','\\r')
+
# Encode
write('begin %o %s\n' % (mode & 0777, filename))
chunk = read(45)
diff --git a/Lib/test/test_uu.py b/Lib/test/test_uu.py
index df41cbc12d..f016bb2c67 100644
--- a/Lib/test/test_uu.py
+++ b/Lib/test/test_uu.py
@@ -9,6 +9,7 @@ from test import test_support as support
import cStringIO
import sys
import uu
+import io
plaintext = "The smooth-scaled python crept over the sleeping dog\n"
@@ -82,6 +83,15 @@ class UUTest(unittest.TestCase):
decoded = codecs.decode(encodedtext, "uu_codec")
self.assertEqual(decoded, plaintext)
+ def test_newlines_escaped(self):
+ # Test newlines are escaped with uu.encode
+ inp = io.BytesIO(plaintext)
+ out = io.BytesIO()
+ filename = "test.txt\n\roverflow.txt"
+ safefilename = b"test.txt\\n\\roverflow.txt"
+ uu.encode(inp, out, filename)
+ self.assertIn(safefilename, out.getvalue())
+
class UUStdIOTest(unittest.TestCase):
def setUp(self):
diff --git a/Lib/uu.py b/Lib/uu.py
index f8fa4c4757..8eaea5960d 100755
--- a/Lib/uu.py
+++ b/Lib/uu.py
@@ -73,6 +73,13 @@ def encode(in_file, out_file, name=None, mode=None):
name = '-'
if mode is None:
mode = 0666
+
+ #
+ # Remove newline chars from name
+ #
+ name = name.replace('\n','\\n')
+ name = name.replace('\r','\\r')
+
#
# Write the data
#
diff --git a/Misc/NEWS.d/next/Security/2019-12-01-22-44-40.bpo-38945.ztmNXc.rst b/Misc/NEWS.d/next/Security/2019-12-01-22-44-40.bpo-38945.ztmNXc.rst
new file mode 100644
index 0000000000..1bf6ed567b
--- /dev/null
+++ b/Misc/NEWS.d/next/Security/2019-12-01-22-44-40.bpo-38945.ztmNXc.rst
@@ -0,0 +1 @@
+Newline characters have been escaped when performing uu encoding to prevent them from overflowing into to content section of the encoded file. This prevents malicious or accidental modification of data during the decoding process. \ No newline at end of file