1""" 2Tests for uu module. 3Nick Mathewson 4""" 5 6import unittest 7from test import support 8 9import sys, os 10import uu 11import io 12 13plaintext = b"The smooth-scaled python crept over the sleeping dog\n" 14 15encodedtext = b"""\ 16M5&AE('-M;V]T:\"US8V%L960@<'ET:&]N(&-R97!T(&]V97(@=&AE('-L965P 17(:6YG(&1O9PH """ 18 19# 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) 34 self._encoding = encoding 35 self._errors = errors 36 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 47def encodedtextwrapped(mode, filename): 48 return (bytes("begin %03o %s\n" % (mode, filename), "ascii") + 49 encodedtext + b"\n \nend\n") 50 51class UUTest(unittest.TestCase): 52 53 def test_encode(self): 54 inp = io.BytesIO(plaintext) 55 out = io.BytesIO() 56 uu.encode(inp, out, "t1") 57 self.assertEqual(out.getvalue(), encodedtextwrapped(0o666, "t1")) 58 inp = io.BytesIO(plaintext) 59 out = io.BytesIO() 60 uu.encode(inp, out, "t1", 0o644) 61 self.assertEqual(out.getvalue(), encodedtextwrapped(0o644, "t1")) 62 63 def test_decode(self): 64 inp = io.BytesIO(encodedtextwrapped(0o666, "t1")) 65 out = io.BytesIO() 66 uu.decode(inp, out) 67 self.assertEqual(out.getvalue(), plaintext) 68 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") 72 ) 73 out = io.BytesIO() 74 uu.decode(inp, out) 75 self.assertEqual(out.getvalue(), plaintext) 76 77 def test_truncatedinput(self): 78 inp = io.BytesIO(b"begin 644 t1\n" + encodedtext) 79 out = io.BytesIO() 80 try: 81 uu.decode(inp, out) 82 self.fail("No exception raised") 83 except uu.Error as e: 84 self.assertEqual(str(e), "Truncated input file") 85 86 def test_missingbegin(self): 87 inp = io.BytesIO(b"") 88 out = io.BytesIO() 89 try: 90 uu.decode(inp, out) 91 self.fail("No exception raised") 92 except uu.Error as e: 93 self.assertEqual(str(e), "No valid begin line found in input file") 94 95 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 117class UUStdIOTest(unittest.TestCase): 118 119 def setUp(self): 120 self.stdin = sys.stdin 121 self.stdout = sys.stdout 122 123 def tearDown(self): 124 sys.stdin = self.stdin 125 sys.stdout = self.stdout 126 127 def test_encode(self): 128 sys.stdin = FakeIO(plaintext.decode("ascii")) 129 sys.stdout = FakeIO() 130 uu.encode("-", "-", "t1", 0o666) 131 self.assertEqual(sys.stdout.getvalue(), 132 encodedtextwrapped(0o666, "t1").decode("ascii")) 133 134 def test_decode(self): 135 sys.stdin = FakeIO(encodedtextwrapped(0o666, "t1").decode("ascii")) 136 sys.stdout = FakeIO() 137 uu.decode("-", "-") 138 stdout = sys.stdout 139 sys.stdout = self.stdout 140 sys.stdin = self.stdin 141 self.assertEqual(stdout.getvalue(), plaintext.decode("ascii")) 142 143class UUFileTest(unittest.TestCase): 144 145 def _kill(self, f): 146 # close and remove file 147 if f is None: 148 return 149 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): 163 self.tmpin = support.TESTFN + "i" 164 self.tmpout = support.TESTFN + "o" 165 166 def tearDown(self): 167 del self.tmpin 168 del self.tmpout 169 170 def test_encode(self): 171 fin = fout = None 172 try: 173 support.unlink(self.tmpin) 174 fin = open(self.tmpin, 'wb') 175 fin.write(plaintext) 176 fin.close() 177 178 fin = open(self.tmpin, 'rb') 179 fout = open(self.tmpout, 'wb') 180 uu.encode(fin, fout, self.tmpin, mode=0o644) 181 fin.close() 182 fout.close() 183 184 fout = open(self.tmpout, 'rb') 185 s = fout.read() 186 fout.close() 187 self.assertEqual(s, encodedtextwrapped(0o644, self.tmpin)) 188 189 # in_file and out_file as filenames 190 uu.encode(self.tmpin, self.tmpout, self.tmpin, mode=0o644) 191 fout = open(self.tmpout, 'rb') 192 s = fout.read() 193 fout.close() 194 self.assertEqual(s, encodedtextwrapped(0o644, self.tmpin)) 195 196 finally: 197 self._kill(fin) 198 self._kill(fout) 199 200 def test_decode(self): 201 f = None 202 try: 203 support.unlink(self.tmpin) 204 f = open(self.tmpin, 'wb') 205 f.write(encodedtextwrapped(0o644, self.tmpout)) 206 f.close() 207 208 f = open(self.tmpin, 'rb') 209 uu.decode(f) 210 f.close() 211 212 f = open(self.tmpout, 'rb') 213 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 220 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 237 def test_decodetwice(self): 238 # Verify that decode() will refuse to overwrite an existing file 239 f = None 240 try: 241 f = io.BytesIO(encodedtextwrapped(0o644, self.tmpout)) 242 243 f = open(self.tmpin, 'rb') 244 uu.decode(f) 245 f.close() 246 247 f = open(self.tmpin, 'rb') 248 self.assertRaises(uu.Error, uu.decode, f) 249 f.close() 250 finally: 251 self._kill(f) 252 253def test_main(): 254 support.run_unittest(UUTest, 255 UUStdIOTest, 256 UUFileTest, 257 ) 258 259if __name__=="__main__": 260 test_main() 261