From d80a3b7457ff64239acba22347dfd4b6c9741da2 Mon Sep 17 00:00:00 2001 From: ila Date: Fri, 16 Aug 2024 01:26:16 +0400 Subject: [PATCH 1/3] Fix object has no attribute 'dataoff' `ext_fnhdr` exists only if call `_appendHdr()` once found a very long file name. Without that, impossible to get `ext_fnhdr_data`. It should be safe to leave `ext_fnhdr_data` as None if no `ext_fnhdr` added since later every `hdrs` will be checked for very long file name and if none of them will meet the condition, `ext_fnhdr_data` is not needed at all. --- osc/util/ar.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osc/util/ar.py b/osc/util/ar.py index 66c02918b..ad32354b3 100644 --- a/osc/util/ar.py +++ b/osc/util/ar.py @@ -147,8 +147,10 @@ def _fixupFilenames(self): """ # read extended header with long file names and then only seek into the right offsets - self.__file.seek(self.ext_fnhdr.dataoff, os.SEEK_SET) - ext_fnhdr_data = self.__file.read(self.ext_fnhdr.size) + ext_fnhdr_data = None + if self.ext_fnhdr: + self.__file.seek(self.ext_fnhdr.dataoff, os.SEEK_SET) + ext_fnhdr_data = self.__file.read(self.ext_fnhdr.size) for h in self.hdrs: if h.file == b'/': @@ -161,6 +163,7 @@ def _fixupFilenames(self): # long file name assert h.file[0:1] == b"/" + assert ext_fnhdr_data is not None start = int(h.file[1:]) end = ext_fnhdr_data.find(b'/', start) From 2f4e479ad1c0d93df16aa2eb9d8f95f2c48cc6ec Mon Sep 17 00:00:00 2001 From: ila Date: Fri, 16 Aug 2024 01:56:41 +0400 Subject: [PATCH 2/3] Restore start symbol check --- osc/util/ar.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osc/util/ar.py b/osc/util/ar.py index ad32354b3..8c501e66c 100644 --- a/osc/util/ar.py +++ b/osc/util/ar.py @@ -161,6 +161,9 @@ def _fixupFilenames(self): h.file = h.file[:-1] continue + if not h.file.startswith(b'/'): + continue + # long file name assert h.file[0:1] == b"/" assert ext_fnhdr_data is not None From 292052912cb2b3c2ce11939c91b4544ac8c2d719 Mon Sep 17 00:00:00 2001 From: Daniel Mach Date: Tue, 20 Aug 2024 10:38:54 +0200 Subject: [PATCH 3/3] Add test for extracting ar archive without long filenames --- tests/fixtures/README | 6 ++++++ tests/fixtures/archive-no-ext_fnhdr.ar | 3 +++ tests/test_util_ar.py | 6 ++++++ 3 files changed, 15 insertions(+) create mode 100644 tests/fixtures/archive-no-ext_fnhdr.ar diff --git a/tests/fixtures/README b/tests/fixtures/README index 2b7fa007f..2801ea7ef 100644 --- a/tests/fixtures/README +++ b/tests/fixtures/README @@ -33,3 +33,9 @@ Create archive.cpio printf "/tmp/foo\0/123\0very-long-long-long-long-name\0very-long-long-long-long-name2\0very-long-name -with-newline\0a\nb\0dir/file\0" | cpio -ocv0 --owner=root:root > archive.cpio + + +Create archive-no-ext_fnhdr.ar +------------------------------ + +ar qP archive-no-ext_fnhdr.ar dir/file diff --git a/tests/fixtures/archive-no-ext_fnhdr.ar b/tests/fixtures/archive-no-ext_fnhdr.ar new file mode 100644 index 000000000..1da64b1bc --- /dev/null +++ b/tests/fixtures/archive-no-ext_fnhdr.ar @@ -0,0 +1,3 @@ +! +dir/file/ 1724142481 1000 1000 100644 14 ` +file-in-a-dir diff --git a/tests/test_util_ar.py b/tests/test_util_ar.py index 227fd4737..099e7b4d1 100644 --- a/tests/test_util_ar.py +++ b/tests/test_util_ar.py @@ -81,6 +81,12 @@ def test_saveTo_abspath(self): # this is supposed to throw an error, extracting files with absolute paths might overwrite system files self.assertRaises(ArError, f.saveTo, self.tmpdir) + def test_no_exthdr(self): + self.archive = os.path.join(FIXTURES_DIR, "archive-no-ext_fnhdr.ar") + self.ar = Ar(self.archive) + self.ar.read() + self.test_saveTo_subdir() + if __name__ == "__main__": unittest.main()