[Python-checkins] bpo-38945: UU Encoding: Don't let newline in filename corrupt the output format (GH-17418) (GH-17444) (#17445)

Ned Deily webhook-mailer at python.org
Sat Mar 21 01:42:58 EDT 2020


https://github.com/python/cpython/commit/8835f465fa94f114dcf865429c0410821d365dae
commit: 8835f465fa94f114dcf865429c0410821d365dae
branch: 3.5
author: Ned Deily <nad at python.org>
committer: GitHub <noreply at github.com>
date: 2020-03-20T22:42:50-07:00
summary:

bpo-38945: UU Encoding: Don't let newline in filename corrupt the output format (GH-17418) (GH-17444) (#17445)

(cherry picked from commit a62ad4730c9b575f140f24074656c0257c86a09a)

Co-authored-by: Matthew Rollings <1211162+stealthcopter at users.noreply.github.com>

files:
A Misc/NEWS.d/next/Security/2019-12-01-22-44-40.bpo-38945.ztmNXc.rst
M Lib/encodings/uu_codec.py
M Lib/test/test_uu.py
M Lib/uu.py

diff --git a/Lib/encodings/uu_codec.py b/Lib/encodings/uu_codec.py
index 2a5728fb5b74a..4e58c62fe9ef0 100644
--- a/Lib/encodings/uu_codec.py
+++ b/Lib/encodings/uu_codec.py
@@ -20,6 +20,10 @@ def uu_encode(input, errors='strict', filename='<data>', mode=0o666):
     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 & 0o777, filename)).encode('ascii'))
     chunk = read(45)
diff --git a/Lib/test/test_uu.py b/Lib/test/test_uu.py
index 25fffbf9936af..4ba0ed8d0f47e 100644
--- a/Lib/test/test_uu.py
+++ b/Lib/test/test_uu.py
@@ -115,6 +115,15 @@ def test_garbage_padding(self):
             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 d68d29374a8bb..3a8c31cff06d8 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 = 0o666
+
+        #
+        # 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 0000000000000..1bf6ed567b241
--- /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



More information about the Python-checkins mailing list