From a016d4e32cc9faa48105d00db275439c3dc93559 Mon Sep 17 00:00:00 2001 From: Matthew Rollings <1211162+stealthcopter@users.noreply.github.com> Date: Tue, 3 Dec 2019 18:18:52 +0000 Subject: [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> --- Lib/encodings/uu_codec.py | 4 ++++ Lib/test/test_uu.py | 10 ++++++++++ Lib/uu.py | 7 +++++++ .../next/Security/2019-12-01-22-44-40.bpo-38945.ztmNXc.rst | 1 + 4 files changed, 22 insertions(+) create mode 100644 Misc/NEWS.d/next/Security/2019-12-01-22-44-40.bpo-38945.ztmNXc.rst diff --git a/Lib/encodings/uu_codec.py b/Lib/encodings/uu_codec.py index 5cb0d2b..fcd5aa4 100644 --- a/Lib/encodings/uu_codec.py +++ b/Lib/encodings/uu_codec.py @@ -31,6 +31,10 @@ def uu_encode(input,errors='strict',filename='',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 df41cbc..f016bb2 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 f8fa4c4..8eaea59 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 0000000..1bf6ed5 --- /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 -- cgit v0.12