blob: ad2f2c59c1089bc82f5d5407bad3d72672181d32 [file] [log] [blame]
Tim Peters48dacc62001-07-11 21:43:42 +00001"""
2Tests for uu module.
3Nick Mathewson
4"""
5
Walter Dörwald411e5a22003-05-06 08:57:41 +00006import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007from test import support
Walter Dörwald411e5a22003-05-06 08:57:41 +00008
Guido van Rossum34d19282007-08-09 01:03:29 +00009import sys, os
Tim Peters48dacc62001-07-11 21:43:42 +000010import uu
Guido van Rossum34d19282007-08-09 01:03:29 +000011import io
Tim Peters48dacc62001-07-11 21:43:42 +000012
Guido van Rossum34d19282007-08-09 01:03:29 +000013plaintext = b"The smooth-scaled python crept over the sleeping dog\n"
Walter Dörwald411e5a22003-05-06 08:57:41 +000014
Guido van Rossum34d19282007-08-09 01:03:29 +000015encodedtext = b"""\
Tim Peters48dacc62001-07-11 21:43:42 +000016M5&AE('-M;V]T:\"US8V%L960@<'ET:&]N(&-R97!T(&]V97(@=&AE('-L965P
17(:6YG(&1O9PH """
Tim Peters48dacc62001-07-11 21:43:42 +000018
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000019# Stolen from io.py
20class FakeIO(io.TextIOWrapper):
21 """Text I/O implementation using an in-memory buffer.
22
23 Can be a used as a drop-in replacement for sys.stdin and sys.stdout.
24 """
25
26 # XXX This is really slow, but fully functional
27
28 def __init__(self, initial_value="", encoding="utf-8",
29 errors="strict", newline="\n"):
30 super(FakeIO, self).__init__(io.BytesIO(),
31 encoding=encoding,
32 errors=errors,
33 newline=newline)
Benjamin Peterson4fa88fa2009-03-04 00:14:51 +000034 self._encoding = encoding
35 self._errors = errors
Alexandre Vassalotti794652d2008-06-11 22:58:36 +000036 if initial_value:
37 if not isinstance(initial_value, str):
38 initial_value = str(initial_value)
39 self.write(initial_value)
40 self.seek(0)
41
42 def getvalue(self):
43 self.flush()
44 return self.buffer.getvalue().decode(self._encoding, self._errors)
45
46
Guido van Rossum34d19282007-08-09 01:03:29 +000047def encodedtextwrapped(mode, filename):
48 return (bytes("begin %03o %s\n" % (mode, filename), "ascii") +
49 encodedtext + b"\n \nend\n")
Tim Peters48dacc62001-07-11 21:43:42 +000050
Walter Dörwald411e5a22003-05-06 08:57:41 +000051class UUTest(unittest.TestCase):
Tim Peters48dacc62001-07-11 21:43:42 +000052
Walter Dörwald411e5a22003-05-06 08:57:41 +000053 def test_encode(self):
Guido van Rossum34d19282007-08-09 01:03:29 +000054 inp = io.BytesIO(plaintext)
55 out = io.BytesIO()
Walter Dörwald411e5a22003-05-06 08:57:41 +000056 uu.encode(inp, out, "t1")
Guido van Rossum34d19282007-08-09 01:03:29 +000057 self.assertEqual(out.getvalue(), encodedtextwrapped(0o666, "t1"))
58 inp = io.BytesIO(plaintext)
59 out = io.BytesIO()
Guido van Rossumcd16bf62007-06-13 18:07:49 +000060 uu.encode(inp, out, "t1", 0o644)
Guido van Rossum34d19282007-08-09 01:03:29 +000061 self.assertEqual(out.getvalue(), encodedtextwrapped(0o644, "t1"))
Tim Peters48dacc62001-07-11 21:43:42 +000062
Walter Dörwald411e5a22003-05-06 08:57:41 +000063 def test_decode(self):
Guido van Rossum34d19282007-08-09 01:03:29 +000064 inp = io.BytesIO(encodedtextwrapped(0o666, "t1"))
65 out = io.BytesIO()
Walter Dörwald411e5a22003-05-06 08:57:41 +000066 uu.decode(inp, out)
67 self.assertEqual(out.getvalue(), plaintext)
Guido van Rossum34d19282007-08-09 01:03:29 +000068 inp = io.BytesIO(
69 b"UUencoded files may contain many lines,\n" +
70 b"even some that have 'begin' in them.\n" +
71 encodedtextwrapped(0o666, "t1")
Walter Dörwald411e5a22003-05-06 08:57:41 +000072 )
Guido van Rossum34d19282007-08-09 01:03:29 +000073 out = io.BytesIO()
Walter Dörwald411e5a22003-05-06 08:57:41 +000074 uu.decode(inp, out)
75 self.assertEqual(out.getvalue(), plaintext)
Tim Peters48dacc62001-07-11 21:43:42 +000076
Walter Dörwald411e5a22003-05-06 08:57:41 +000077 def test_truncatedinput(self):
Guido van Rossum34d19282007-08-09 01:03:29 +000078 inp = io.BytesIO(b"begin 644 t1\n" + encodedtext)
79 out = io.BytesIO()
Walter Dörwald411e5a22003-05-06 08:57:41 +000080 try:
81 uu.decode(inp, out)
Andrew Svetlov737fb892012-12-18 21:14:22 +020082 self.fail("No exception raised")
Guido van Rossumb940e112007-01-10 16:19:56 +000083 except uu.Error as e:
Walter Dörwald411e5a22003-05-06 08:57:41 +000084 self.assertEqual(str(e), "Truncated input file")
Tim Peters48dacc62001-07-11 21:43:42 +000085
Walter Dörwald411e5a22003-05-06 08:57:41 +000086 def test_missingbegin(self):
Guido van Rossum34d19282007-08-09 01:03:29 +000087 inp = io.BytesIO(b"")
88 out = io.BytesIO()
Walter Dörwald411e5a22003-05-06 08:57:41 +000089 try:
90 uu.decode(inp, out)
Andrew Svetlov737fb892012-12-18 21:14:22 +020091 self.fail("No exception raised")
Guido van Rossumb940e112007-01-10 16:19:56 +000092 except uu.Error as e:
Walter Dörwald411e5a22003-05-06 08:57:41 +000093 self.assertEqual(str(e), "No valid begin line found in input file")
Tim Peters48dacc62001-07-11 21:43:42 +000094
Serhiy Storchaka519114d2014-11-07 14:04:37 +020095 def test_garbage_padding(self):
96 # Issue #22406
97 encodedtext = (
98 b"begin 644 file\n"
99 # length 1; bits 001100 111111 111111 111111
100 b"\x21\x2C\x5F\x5F\x5F\n"
101 b"\x20\n"
102 b"end\n"
103 )
104 plaintext = b"\x33" # 00110011
105
106 with self.subTest("uu.decode()"):
107 inp = io.BytesIO(encodedtext)
108 out = io.BytesIO()
109 uu.decode(inp, out, quiet=True)
110 self.assertEqual(out.getvalue(), plaintext)
111
112 with self.subTest("uu_codec"):
113 import codecs
114 decoded = codecs.decode(encodedtext, "uu_codec")
115 self.assertEqual(decoded, plaintext)
116
Walter Dörwald411e5a22003-05-06 08:57:41 +0000117class UUStdIOTest(unittest.TestCase):
Tim Peters48dacc62001-07-11 21:43:42 +0000118
Walter Dörwald411e5a22003-05-06 08:57:41 +0000119 def setUp(self):
120 self.stdin = sys.stdin
121 self.stdout = sys.stdout
Tim Peters48dacc62001-07-11 21:43:42 +0000122
Walter Dörwald411e5a22003-05-06 08:57:41 +0000123 def tearDown(self):
124 sys.stdin = self.stdin
125 sys.stdout = self.stdout
Barry Warsawd1795702001-08-17 20:00:11 +0000126
Walter Dörwald411e5a22003-05-06 08:57:41 +0000127 def test_encode(self):
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000128 sys.stdin = FakeIO(plaintext.decode("ascii"))
129 sys.stdout = FakeIO()
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000130 uu.encode("-", "-", "t1", 0o666)
Guido van Rossum34d19282007-08-09 01:03:29 +0000131 self.assertEqual(sys.stdout.getvalue(),
132 encodedtextwrapped(0o666, "t1").decode("ascii"))
Walter Dörwald411e5a22003-05-06 08:57:41 +0000133
134 def test_decode(self):
Alexandre Vassalotti794652d2008-06-11 22:58:36 +0000135 sys.stdin = FakeIO(encodedtextwrapped(0o666, "t1").decode("ascii"))
136 sys.stdout = FakeIO()
Walter Dörwald411e5a22003-05-06 08:57:41 +0000137 uu.decode("-", "-")
Guido van Rossum34d19282007-08-09 01:03:29 +0000138 stdout = sys.stdout
139 sys.stdout = self.stdout
140 sys.stdin = self.stdin
141 self.assertEqual(stdout.getvalue(), plaintext.decode("ascii"))
Walter Dörwald411e5a22003-05-06 08:57:41 +0000142
143class UUFileTest(unittest.TestCase):
144
145 def _kill(self, f):
146 # close and remove file
Guido van Rossum34d19282007-08-09 01:03:29 +0000147 if f is None:
148 return
Walter Dörwald411e5a22003-05-06 08:57:41 +0000149 try:
150 f.close()
151 except (SystemExit, KeyboardInterrupt):
152 raise
153 except:
154 pass
155 try:
156 os.unlink(f.name)
157 except (SystemExit, KeyboardInterrupt):
158 raise
159 except:
160 pass
161
162 def setUp(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000163 self.tmpin = support.TESTFN + "i"
164 self.tmpout = support.TESTFN + "o"
Walter Dörwald411e5a22003-05-06 08:57:41 +0000165
166 def tearDown(self):
167 del self.tmpin
168 del self.tmpout
169
170 def test_encode(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000171 fin = fout = None
Walter Dörwald411e5a22003-05-06 08:57:41 +0000172 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000173 support.unlink(self.tmpin)
Thomas Woutersb2137042007-02-01 18:02:27 +0000174 fin = open(self.tmpin, 'wb')
Walter Dörwald411e5a22003-05-06 08:57:41 +0000175 fin.write(plaintext)
176 fin.close()
177
Thomas Woutersb2137042007-02-01 18:02:27 +0000178 fin = open(self.tmpin, 'rb')
Guido van Rossum34d19282007-08-09 01:03:29 +0000179 fout = open(self.tmpout, 'wb')
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000180 uu.encode(fin, fout, self.tmpin, mode=0o644)
Walter Dörwald411e5a22003-05-06 08:57:41 +0000181 fin.close()
182 fout.close()
183
Guido van Rossum34d19282007-08-09 01:03:29 +0000184 fout = open(self.tmpout, 'rb')
Walter Dörwald411e5a22003-05-06 08:57:41 +0000185 s = fout.read()
186 fout.close()
Guido van Rossum34d19282007-08-09 01:03:29 +0000187 self.assertEqual(s, encodedtextwrapped(0o644, self.tmpin))
Walter Dörwald705fd472005-11-21 18:55:56 +0000188
189 # in_file and out_file as filenames
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000190 uu.encode(self.tmpin, self.tmpout, self.tmpin, mode=0o644)
Guido van Rossum34d19282007-08-09 01:03:29 +0000191 fout = open(self.tmpout, 'rb')
Walter Dörwald705fd472005-11-21 18:55:56 +0000192 s = fout.read()
193 fout.close()
Guido van Rossum34d19282007-08-09 01:03:29 +0000194 self.assertEqual(s, encodedtextwrapped(0o644, self.tmpin))
Walter Dörwald705fd472005-11-21 18:55:56 +0000195
Walter Dörwald411e5a22003-05-06 08:57:41 +0000196 finally:
197 self._kill(fin)
198 self._kill(fout)
199
200 def test_decode(self):
Guido van Rossum34d19282007-08-09 01:03:29 +0000201 f = None
Walter Dörwald411e5a22003-05-06 08:57:41 +0000202 try:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000203 support.unlink(self.tmpin)
Guido van Rossum34d19282007-08-09 01:03:29 +0000204 f = open(self.tmpin, 'wb')
205 f.write(encodedtextwrapped(0o644, self.tmpout))
Walter Dörwald411e5a22003-05-06 08:57:41 +0000206 f.close()
207
Guido van Rossum34d19282007-08-09 01:03:29 +0000208 f = open(self.tmpin, 'rb')
Walter Dörwald411e5a22003-05-06 08:57:41 +0000209 uu.decode(f)
210 f.close()
211
Guido van Rossum34d19282007-08-09 01:03:29 +0000212 f = open(self.tmpout, 'rb')
Walter Dörwald411e5a22003-05-06 08:57:41 +0000213 s = f.read()
214 f.close()
215 self.assertEqual(s, plaintext)
216 # XXX is there an xp way to verify the mode?
217 finally:
218 self._kill(f)
219
Antoine Pitrouf5698262010-10-31 16:04:14 +0000220 def test_decode_filename(self):
221 f = None
222 try:
223 support.unlink(self.tmpin)
224 f = open(self.tmpin, 'wb')
225 f.write(encodedtextwrapped(0o644, self.tmpout))
226 f.close()
227
228 uu.decode(self.tmpin)
229
230 f = open(self.tmpout, 'rb')
231 s = f.read()
232 f.close()
233 self.assertEqual(s, plaintext)
234 finally:
235 self._kill(f)
236
Walter Dörwald411e5a22003-05-06 08:57:41 +0000237 def test_decodetwice(self):
238 # Verify that decode() will refuse to overwrite an existing file
Guido van Rossum34d19282007-08-09 01:03:29 +0000239 f = None
Walter Dörwald411e5a22003-05-06 08:57:41 +0000240 try:
Guido van Rossum34d19282007-08-09 01:03:29 +0000241 f = io.BytesIO(encodedtextwrapped(0o644, self.tmpout))
Walter Dörwald411e5a22003-05-06 08:57:41 +0000242
Guido van Rossum34d19282007-08-09 01:03:29 +0000243 f = open(self.tmpin, 'rb')
Walter Dörwald411e5a22003-05-06 08:57:41 +0000244 uu.decode(f)
245 f.close()
246
Guido van Rossum34d19282007-08-09 01:03:29 +0000247 f = open(self.tmpin, 'rb')
Walter Dörwald411e5a22003-05-06 08:57:41 +0000248 self.assertRaises(uu.Error, uu.decode, f)
249 f.close()
250 finally:
251 self._kill(f)
252
253def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000254 support.run_unittest(UUTest,
Guido van Rossum34d19282007-08-09 01:03:29 +0000255 UUStdIOTest,
256 UUFileTest,
257 )
Walter Dörwald411e5a22003-05-06 08:57:41 +0000258
259if __name__=="__main__":
260 test_main()