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

Guido van Rossum webhook-mailer at python.org
Tue Dec 3 13:19:01 EST 2019


https://github.com/python/cpython/commit/a016d4e32cc9faa48105d00db275439c3dc93559
commit: a016d4e32cc9faa48105d00db275439c3dc93559
branch: 2.7
author: Matthew Rollings <1211162+stealthcopter at users.noreply.github.com>
committer: Guido van Rossum <guido at python.org>
date: 2019-12-03T10:18:52-08:00
summary:

[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 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 5cb0d2b13e071..fcd5aa45a9708 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 df41cbc12d40d..f016bb2c67ea2 100644
--- a/Lib/test/test_uu.py
+++ b/Lib/test/test_uu.py
@@ -9,6 +9,7 @@
 import cStringIO
 import sys
 import uu
+import io
 
 plaintext = "The smooth-scaled python crept over the sleeping dog\n"
 
@@ -82,6 +83,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 f8fa4c4757661..8eaea5960dffe 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 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