diff -Nru apt-clone-0.3.1~ubuntu11/apt-clone apt-clone-0.3.1~ubuntu11.1/apt-clone --- apt-clone-0.3.1~ubuntu11/apt-clone 2013-09-10 08:46:00.000000000 +0000 +++ apt-clone-0.3.1~ubuntu11.1/apt-clone 2014-08-20 21:17:22.000000000 +0000 @@ -22,6 +22,7 @@ import argparse from apt_clone import AptClone + if __name__ == "__main__": # command line parser diff -Nru apt-clone-0.3.1~ubuntu11/apt_clone.py apt-clone-0.3.1~ubuntu11.1/apt_clone.py --- apt-clone-0.3.1~ubuntu11/apt_clone.py 2014-02-13 10:54:25.000000000 +0000 +++ apt-clone-0.3.1~ubuntu11.1/apt_clone.py 2014-08-20 21:19:01.000000000 +0000 @@ -247,8 +247,11 @@ def _add_file_to_tar_with_password_check(self, tar, sources, scrub, arcname): if scrub: - with tempfile.NamedTemporaryFile(mode='wb') as source_copy, open(sources, 'r') as f: + with tempfile.NamedTemporaryFile(mode='wb') as source_copy, open(sources, 'rb') as f: for line in f.readlines(): + # compat with both py2/py3 + if type(line) is bytes: + line = line.decode("UTF-8") if re.search('/[^/@:]*:[^/@:]*@', line): line = re.sub('/[^/@:]*:[^/@:]*@', '/USERNAME:PASSWORD@', line) @@ -256,9 +259,9 @@ # open in Unicode mode in Python 2. We can remove this # once ubuntu-release-upgrader is run under Python 3 # (i.e. after Ubuntu 14.04). - if line is not bytes: - line = line.encode("UTF-8") - source_copy.write(line) + #if line is not bytes: + # line = line.encode("UTF-8") + source_copy.write(line.encode("utf-8")) source_copy.flush() tar.add(source_copy.name, arcname=arcname) else: Binary files /tmp/y3I9TAqdbB/apt-clone-0.3.1~ubuntu11/apt_clone.pyc and /tmp/9EWGQ5DH22/apt-clone-0.3.1~ubuntu11.1/apt_clone.pyc differ diff -Nru apt-clone-0.3.1~ubuntu11/debian/changelog apt-clone-0.3.1~ubuntu11.1/debian/changelog --- apt-clone-0.3.1~ubuntu11/debian/changelog 2014-02-26 20:53:03.000000000 +0000 +++ apt-clone-0.3.1~ubuntu11.1/debian/changelog 2014-08-20 21:21:48.000000000 +0000 @@ -1,3 +1,10 @@ +apt-clone (0.3.1~ubuntu11.1) trusty-proposed; urgency=medium + + * Resolve unicode decode error for sources.list files if locale is + unsupported. (LP: #1309447) + + -- Brian Murray Wed, 20 Aug 2014 14:21:21 -0700 + apt-clone (0.3.1~ubuntu11) trusty; urgency=medium * lp:~brian-murray/apt-clone/test_clone_upgrade_ports: diff -Nru apt-clone-0.3.1~ubuntu11/tests/test_clone.py apt-clone-0.3.1~ubuntu11.1/tests/test_clone.py --- apt-clone-0.3.1~ubuntu11/tests/test_clone.py 2013-09-10 08:46:00.000000000 +0000 +++ apt-clone-0.3.1~ubuntu11.1/tests/test_clone.py 2014-08-20 21:17:22.000000000 +0000 @@ -1,5 +1,5 @@ #!/usr/bin/python3 - +# -*- coding: utf-8 -*- from __future__ import print_function import apt @@ -195,5 +195,6 @@ self.assertFalse("/etc/issue" in unowned) #print("\n".join(sorted(unowned))) + if __name__ == "__main__": unittest.main() diff -Nru apt-clone-0.3.1~ubuntu11/tests/test_lp1309447.py apt-clone-0.3.1~ubuntu11.1/tests/test_lp1309447.py --- apt-clone-0.3.1~ubuntu11/tests/test_lp1309447.py 1970-01-01 00:00:00.000000000 +0000 +++ apt-clone-0.3.1~ubuntu11.1/tests/test_lp1309447.py 2014-08-20 21:17:22.000000000 +0000 @@ -0,0 +1,51 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- + +from __future__ import print_function + +import os +import sys +import unittest + +# this is important +os.environ["LANG"] = "C" + + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) +from apt_clone import AptClone + + +class MockTar(object): + def add(self, source, arcname): + with open(source, "rb") as f: + self.data = f.read().decode("utf-8") + + +class TestClone(unittest.TestCase): + + def setUp(self): + self.apt_clone = AptClone() + self.test_sources_fname = "test-sources.list" + with open(self.test_sources_fname, "wb") as f: + f.write(u"""# äüö +deb http://mvo:secret@archive.u.c/ ubuntu main +""".encode("utf-8")) + + def tearDown(self): + os.unlink(self.test_sources_fname) + + def test_scrub_file_from_passwords(self): + """Regression test for utf8 crash LP: #1309447""" + mock_tar = MockTar() + self.apt_clone._add_file_to_tar_with_password_check( + mock_tar, self.test_sources_fname, scrub=True, + arcname="some-archname") + # see if we got the expected data + self.assertNotIn("mvo:secret", mock_tar.data) + self.assertEqual(mock_tar.data, u"""# äüö +deb http://USERNAME:PASSWORD@archive.u.c/ ubuntu main +""") + + +if __name__ == "__main__": + unittest.main()