diff --git a/pkg/private/deb/make_deb.py b/pkg/private/deb/make_deb.py index 8fae6b7b..ce832c31 100644 --- a/pkg/private/deb/make_deb.py +++ b/pkg/private/deb/make_deb.py @@ -101,7 +101,12 @@ def AddArFileEntry(fileobj, filename, if isinstance(content, (str, bytes)): content_len, content = ConvertToFileLike(content, content_len, io.BytesIO) inputs = [ - (filename + '/').ljust(16), # filename (SysV) + # SysV/GNU ar convention is /. + # That breaks BSD version of ar, which does not support spaces in names. + # macos is BSD style, most linux are GNU style. + # dbpk-deb writes without a slash + # dpkg is happy to read either way since about 1.15.6 + filename.ljust(16), # filename (no '/' terminator, matches dpkg-deb) str(timestamp).ljust(12), # timestamp str(owner_id).ljust(6), # owner id str(group_id).ljust(6), # group id diff --git a/tests/deb/pkg_deb_test.py b/tests/deb/pkg_deb_test.py index 120ada1a..81b65690 100644 --- a/tests/deb/pkg_deb_test.py +++ b/tests/deb/pkg_deb_test.py @@ -133,6 +133,28 @@ def assert_tar_stream_content(self, data, expected, match_order=True): if i < len(expected): self.fail('Missing file %s' % expected[i]) + def test_ar_member_names(self): + # Read the raw ar headers rather than using SimpleArReader, which + # tolerates the SysV '/' name terminator. dpkg-deb writes plain names + # padded with spaces, so we should too. + names = [] + with open(self.deb_path, 'rb') as f: + self.assertEqual(f.read(8), b'!\n') + while True: + header = f.read(60) + if not header: + break + self.assertEqual(len(header), 60) + self.assertEqual(header[58:60], b'\x60\x0a') + names.append(header[0:16]) + size = int(header[48:58].strip()) + f.seek(size + (size % 2), os.SEEK_CUR) + self.assertEqual(names, [ + b'debian-binary ', + b'control.tar.gz ', + b'data.tar.gz ', + ]) + def test_expected_files(self): # Check the set of 'test-tar-basic-*' smoke test. expected = [