summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorXiang Zhang <angwerzx@126.com>2017-05-03 03:16:21 (GMT)
committerGitHub <noreply@github.com>2017-05-03 03:16:21 (GMT)
commit13f1f423fac39f8f14a3ce919dd236975517d5c6 (patch)
tree674546ddbbbfaf930c0087eeb1621fab11e25d5f /Lib
parent0360a9d015ddbc4e3d58e3ab4b433da27bf1db3a (diff)
downloadcpython-13f1f423fac39f8f14a3ce919dd236975517d5c6.zip
cpython-13f1f423fac39f8f14a3ce919dd236975517d5c6.tar.gz
cpython-13f1f423fac39f8f14a3ce919dd236975517d5c6.tar.bz2
bpo-30103: Allow Uuencode in Python using backtick as zero instead of space (#1326)
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_binascii.py36
-rw-r--r--Lib/test/test_uu.py83
-rwxr-xr-xLib/uu.py13
3 files changed, 81 insertions, 51 deletions
diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py
index 6b3e437..8fa57cd 100644
--- a/Lib/test/test_binascii.py
+++ b/Lib/test/test_binascii.py
@@ -112,29 +112,41 @@ class BinASCIITest(unittest.TestCase):
def test_uu(self):
MAX_UU = 45
- lines = []
- for i in range(0, len(self.data), MAX_UU):
- b = self.type2test(self.rawdata[i:i+MAX_UU])
- a = binascii.b2a_uu(b)
- lines.append(a)
- res = bytes()
- for line in lines:
- a = self.type2test(line)
- b = binascii.a2b_uu(a)
- res += b
- self.assertEqual(res, self.rawdata)
+ for backtick in (True, False):
+ lines = []
+ for i in range(0, len(self.data), MAX_UU):
+ b = self.type2test(self.rawdata[i:i+MAX_UU])
+ a = binascii.b2a_uu(b, backtick=backtick)
+ lines.append(a)
+ res = bytes()
+ for line in lines:
+ a = self.type2test(line)
+ b = binascii.a2b_uu(a)
+ res += b
+ self.assertEqual(res, self.rawdata)
self.assertEqual(binascii.a2b_uu(b"\x7f"), b"\x00"*31)
self.assertEqual(binascii.a2b_uu(b"\x80"), b"\x00"*32)
self.assertEqual(binascii.a2b_uu(b"\xff"), b"\x00"*31)
self.assertRaises(binascii.Error, binascii.a2b_uu, b"\xff\x00")
self.assertRaises(binascii.Error, binascii.a2b_uu, b"!!!!")
-
self.assertRaises(binascii.Error, binascii.b2a_uu, 46*b"!")
# Issue #7701 (crash on a pydebug build)
self.assertEqual(binascii.b2a_uu(b'x'), b'!> \n')
+ self.assertEqual(binascii.b2a_uu(b''), b' \n')
+ self.assertEqual(binascii.b2a_uu(b'', backtick=True), b'`\n')
+ self.assertEqual(binascii.a2b_uu(b' \n'), b'')
+ self.assertEqual(binascii.a2b_uu(b'`\n'), b'')
+ self.assertEqual(binascii.b2a_uu(b'\x00Cat'), b'$ $-A= \n')
+ self.assertEqual(binascii.b2a_uu(b'\x00Cat', backtick=True),
+ b'$`$-A=```\n')
+ self.assertEqual(binascii.a2b_uu(b'$`$-A=```\n'),
+ binascii.a2b_uu(b'$ $-A= \n'))
+ with self.assertRaises(TypeError):
+ binascii.b2a_uu(b"", True)
+
def test_crc_hqx(self):
crc = binascii.crc_hqx(self.type2test(b"Test the CRC-32 of"), 0)
crc = binascii.crc_hqx(self.type2test(b" this string."), crc)
diff --git a/Lib/test/test_uu.py b/Lib/test/test_uu.py
index ad2f2c5..11bd08c 100644
--- a/Lib/test/test_uu.py
+++ b/Lib/test/test_uu.py
@@ -10,11 +10,11 @@ import sys, os
import uu
import io
-plaintext = b"The smooth-scaled python crept over the sleeping dog\n"
+plaintext = b"The symbols on top of your keyboard are !@#$%^&*()_+|~\n"
encodedtext = b"""\
-M5&AE('-M;V]T:\"US8V%L960@<'ET:&]N(&-R97!T(&]V97(@=&AE('-L965P
-(:6YG(&1O9PH """
+M5&AE('-Y;6)O;',@;VX@=&]P(&]F('EO=7(@:V5Y8F]A<F0@87)E("% (R0E
+*7B8J*"E?*WQ^"@ """
# Stolen from io.py
class FakeIO(io.TextIOWrapper):
@@ -44,9 +44,14 @@ class FakeIO(io.TextIOWrapper):
return self.buffer.getvalue().decode(self._encoding, self._errors)
-def encodedtextwrapped(mode, filename):
- return (bytes("begin %03o %s\n" % (mode, filename), "ascii") +
- encodedtext + b"\n \nend\n")
+def encodedtextwrapped(mode, filename, backtick=False):
+ if backtick:
+ res = (bytes("begin %03o %s\n" % (mode, filename), "ascii") +
+ encodedtext.replace(b' ', b'`') + b"\n`\nend\n")
+ else:
+ res = (bytes("begin %03o %s\n" % (mode, filename), "ascii") +
+ encodedtext + b"\n \nend\n")
+ return res
class UUTest(unittest.TestCase):
@@ -59,20 +64,27 @@ class UUTest(unittest.TestCase):
out = io.BytesIO()
uu.encode(inp, out, "t1", 0o644)
self.assertEqual(out.getvalue(), encodedtextwrapped(0o644, "t1"))
+ inp = io.BytesIO(plaintext)
+ out = io.BytesIO()
+ uu.encode(inp, out, "t1", backtick=True)
+ self.assertEqual(out.getvalue(), encodedtextwrapped(0o666, "t1", True))
+ with self.assertRaises(TypeError):
+ uu.encode(inp, out, "t1", 0o644, True)
def test_decode(self):
- inp = io.BytesIO(encodedtextwrapped(0o666, "t1"))
- out = io.BytesIO()
- uu.decode(inp, out)
- self.assertEqual(out.getvalue(), plaintext)
- inp = io.BytesIO(
- b"UUencoded files may contain many lines,\n" +
- b"even some that have 'begin' in them.\n" +
- encodedtextwrapped(0o666, "t1")
- )
- out = io.BytesIO()
- uu.decode(inp, out)
- self.assertEqual(out.getvalue(), plaintext)
+ for backtick in True, False:
+ inp = io.BytesIO(encodedtextwrapped(0o666, "t1", backtick=backtick))
+ out = io.BytesIO()
+ uu.decode(inp, out)
+ self.assertEqual(out.getvalue(), plaintext)
+ inp = io.BytesIO(
+ b"UUencoded files may contain many lines,\n" +
+ b"even some that have 'begin' in them.\n" +
+ encodedtextwrapped(0o666, "t1", backtick=backtick)
+ )
+ out = io.BytesIO()
+ uu.decode(inp, out)
+ self.assertEqual(out.getvalue(), plaintext)
def test_truncatedinput(self):
inp = io.BytesIO(b"begin 644 t1\n" + encodedtext)
@@ -94,25 +106,33 @@ class UUTest(unittest.TestCase):
def test_garbage_padding(self):
# Issue #22406
- encodedtext = (
+ encodedtext1 = (
b"begin 644 file\n"
# length 1; bits 001100 111111 111111 111111
b"\x21\x2C\x5F\x5F\x5F\n"
b"\x20\n"
b"end\n"
)
+ encodedtext2 = (
+ b"begin 644 file\n"
+ # length 1; bits 001100 111111 111111 111111
+ b"\x21\x2C\x5F\x5F\x5F\n"
+ b"\x60\n"
+ b"end\n"
+ )
plaintext = b"\x33" # 00110011
- with self.subTest("uu.decode()"):
- inp = io.BytesIO(encodedtext)
- out = io.BytesIO()
- uu.decode(inp, out, quiet=True)
- self.assertEqual(out.getvalue(), plaintext)
+ for encodedtext in encodedtext1, encodedtext2:
+ with self.subTest("uu.decode()"):
+ inp = io.BytesIO(encodedtext)
+ out = io.BytesIO()
+ uu.decode(inp, out, quiet=True)
+ self.assertEqual(out.getvalue(), plaintext)
- with self.subTest("uu_codec"):
- import codecs
- decoded = codecs.decode(encodedtext, "uu_codec")
- self.assertEqual(decoded, plaintext)
+ with self.subTest("uu_codec"):
+ import codecs
+ decoded = codecs.decode(encodedtext, "uu_codec")
+ self.assertEqual(decoded, plaintext)
class UUStdIOTest(unittest.TestCase):
@@ -250,11 +270,6 @@ class UUFileTest(unittest.TestCase):
finally:
self._kill(f)
-def test_main():
- support.run_unittest(UUTest,
- UUStdIOTest,
- UUFileTest,
- )
if __name__=="__main__":
- test_main()
+ unittest.main()
diff --git a/Lib/uu.py b/Lib/uu.py
index d68d293..8333e86 100755
--- a/Lib/uu.py
+++ b/Lib/uu.py
@@ -26,8 +26,8 @@
"""Implementation of the UUencode and UUdecode functions.
-encode(in_file, out_file [,name, mode])
-decode(in_file [, out_file, mode])
+encode(in_file, out_file [,name, mode], *, backtick=False)
+decode(in_file [, out_file, mode, quiet])
"""
import binascii
@@ -39,7 +39,7 @@ __all__ = ["Error", "encode", "decode"]
class Error(Exception):
pass
-def encode(in_file, out_file, name=None, mode=None):
+def encode(in_file, out_file, name=None, mode=None, *, backtick=False):
"""Uuencode file"""
#
# If in_file is a pathname open it and change defaults
@@ -79,9 +79,12 @@ def encode(in_file, out_file, name=None, mode=None):
out_file.write(('begin %o %s\n' % ((mode & 0o777), name)).encode("ascii"))
data = in_file.read(45)
while len(data) > 0:
- out_file.write(binascii.b2a_uu(data))
+ out_file.write(binascii.b2a_uu(data, backtick=backtick))
data = in_file.read(45)
- out_file.write(b' \nend\n')
+ if backtick:
+ out_file.write(b'`\nend\n')
+ else:
+ out_file.write(b' \nend\n')
finally:
for f in opened_files:
f.close()