From 1ba3e04ccf39e9c23216a2e943268491c15024ae Mon Sep 17 00:00:00 2001 From: nyuware Date: Thu, 21 Mar 2024 14:54:55 +0100 Subject: [PATCH] fix(cpio): Fix dupplicated CPIO entries by overwriting them. --- .../cpio/cpio_binary/__input__/duplicate_entries.cpio | 3 +++ .../__output__/duplicate_entries.cpio_extract/colors/blue | 3 +++ .../duplicate_entries.cpio_extract/colors/blue.txt | 3 +++ .../duplicate_entries.cpio_extract/colors/orange.txt | 3 +++ .../__output__/duplicate_entries.cpio_extract/colors/purple | 1 + .../duplicate_entries.cpio_extract/colors/purple.txt | 3 +++ unblob/file_utils.py | 2 +- unblob/handlers/archive/cpio.py | 5 +++++ 8 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/integration/archive/cpio/cpio_binary/__input__/duplicate_entries.cpio create mode 100644 tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/blue create mode 100644 tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/blue.txt create mode 100644 tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/orange.txt create mode 120000 tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/purple create mode 100644 tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/purple.txt diff --git a/tests/integration/archive/cpio/cpio_binary/__input__/duplicate_entries.cpio b/tests/integration/archive/cpio/cpio_binary/__input__/duplicate_entries.cpio new file mode 100644 index 0000000000..da289dc9d1 --- /dev/null +++ b/tests/integration/archive/cpio/cpio_binary/__input__/duplicate_entries.cpio @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fab950a545cff6286c14c8736f532a1204c217de2e1a32f66e83655c7196a7ab +size 1024 diff --git a/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/blue b/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/blue new file mode 100644 index 0000000000..1fc5aa04b5 --- /dev/null +++ b/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/blue @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0bee6616b5e5eae6799cb4525a884a82e7161614f11122bbdf4383b2ac05998 +size 5 diff --git a/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/blue.txt b/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/blue.txt new file mode 100644 index 0000000000..d6be4551ee --- /dev/null +++ b/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/blue.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b946a10c9133c481c9c95234cb8d61a5c063388721f22021ff30363e1bfaa3b0 +size 13 diff --git a/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/orange.txt b/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/orange.txt new file mode 100644 index 0000000000..5c357c8346 --- /dev/null +++ b/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/orange.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6afd32ccf0462f3660d9fe54596a8c519d9478619c9798bc56bec0ba3ac1a7a3 +size 15 diff --git a/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/purple b/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/purple new file mode 120000 index 0000000000..59576e0fdc --- /dev/null +++ b/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/purple @@ -0,0 +1 @@ +purple.txt \ No newline at end of file diff --git a/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/purple.txt b/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/purple.txt new file mode 100644 index 0000000000..52f323b2c5 --- /dev/null +++ b/tests/integration/archive/cpio/cpio_binary/__output__/duplicate_entries.cpio_extract/colors/purple.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:596157e5858a0c647af6a4f55945b9c09ed70dc3f5d0e3db248ea5d5136e8ad3 +size 7 diff --git a/unblob/file_utils.py b/unblob/file_utils.py index d53651d4a2..e532be6ab5 100644 --- a/unblob/file_utils.py +++ b/unblob/file_utils.py @@ -628,7 +628,7 @@ def open( # noqa: A003 def unlink(self, path): """Delete file within extraction path.""" - logger.debug("unlink file", file_path=path) + logger.debug("unlink file", file_path=path, _verbosity=3) safe_path = self._get_extraction_path(path, "unlink") safe_path.unlink(missing_ok=True) diff --git a/unblob/handlers/archive/cpio.py b/unblob/handlers/archive/cpio.py index 43dc2836a4..52c743eb32 100644 --- a/unblob/handlers/archive/cpio.py +++ b/unblob/handlers/archive/cpio.py @@ -210,6 +210,11 @@ def dump_entries(self, fs: FileSystem): if entry.path.name in ("", "."): continue + # There are cases where CPIO archives have duplicated entries + # We then unlink the files to overwrite them and avoid an error. + if not stat.S_ISDIR(entry.mode): + fs.unlink(entry.path) + if stat.S_ISREG(entry.mode): fs.carve(entry.path, self.file, entry.start_offset, entry.size) elif stat.S_ISDIR(entry.mode):