Package: depthcharge-tools
Version: 0.6.2-5
Tags: patch upstream
Control: found -1 0.6.1-1
X-Debbugs-CC: [email protected]
If the lzma package is installed, "depthchargectl build" fails:
$ depthchargectl build --board amd64-generic -vvv
[...]
Failed while creating depthcharge image.
Traceback (most recent call last):
File
"/usr/lib/python3/dist-packages/depthcharge_tools/depthchargectl/_build.py",
line 558, in __call__
mkdepthcharge(
~~~~~~~~~~~~~^
arch=self.board.arch,
^^^^^^^^^^^^^^^^^^^^^
...<12 lines>...
verbosity=self.verbosity,
^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/usr/lib/python3/dist-packages/depthcharge_tools/utils/argparse.py",
line 863, in __normal_call
retval = inst(*args, **kwargs)
File "/usr/lib/python3/dist-packages/depthcharge_tools/utils/argparse.py",
line 799, in __call__
return call(self)
File "/usr/lib/python3/dist-packages/depthcharge_tools/mkdepthcharge.py",
line 960, in __call__
with vmlinuz.open("r+b") as f, mmap(f.fileno(), 0) as data:
~~~~^^^^^^^^^^^^^^^
ValueError: cannot mmap an empty file
[...]
The reason is that d-t tries decompressing with available programs to see
if the file is compressed, and "lzma -dc /boot/vmlinuz-$(uname -r)"
returns empty output with exit status zero even though the file isn't
compressed by lzma. So we end up trying to process the empty output as
the kernel binary.
Regardless of if the lzma behaviour is a bug, we should check against
this successful-but-empty decompression result when checking if files
are compressed to avoid this.
Luckily lzma isn't automatically installed along with kernel or
initramfs-tools etc., and depthcharge-tools depends on xz-utils which
provides lzma anyway, so I guess it wouldn't be installed except if
installed explicitly (as I did for testing).
Attaching patch I'm planning to commit upstream.
-- System Information:
Debian Release: forky/sid
APT prefers buildd-unstable
APT policy: (500, 'buildd-unstable'), (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: arm64, armhf, i386
Kernel: Linux 7.1.8+deb14.1-amd64 (SMP w/8 CPU threads; PREEMPT)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8),
LANGUAGE=en_GB:en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
Versions of packages depthcharge-tools depends on:
ii cgpt 0~R106-15054.B+dfsg-0.1
ii device-tree-compiler 1.7.2-2+b3
ii linux-base 4.16
ii lz4 1.10.0-10
ii python3 3.13.9-3+b1
ii python3-packaging 26.2-2
ii u-boot-tools 2025.01-3.2
ii vboot-kernel-utils 0~R106-15054.B+dfsg-0.1
ii vboot-utils 0~R106-15054.B+dfsg-0.1
ii xz-utils 5.8.3-1
depthcharge-tools recommends no packages.
Versions of packages depthcharge-tools suggests:
ii bzip2 1.0.8-6+b2
ii lzop 1.04-2
ii zstd 1.5.7+dfsg-4
-- no debconf informationFrom 7d44744fc224b06ee37487de22f9f36608a5f5e3 Mon Sep 17 00:00:00 2001
From: Alper Nebi Yasak <[email protected]>
Date: Thu, 9 Jul 2026 11:25:06 +0300
Subject: [PATCH] utils: pathlib: Avoid returning empty decompression output
We try to decompress input files with the usual compression tools to use
the decompressed versions which would be the actual bootable artifacts.
If the lzma Debian package is installed, that one provides the lzma
compressor instead of the xz-utils package, and causes `depthchargectl
build` to fail with an error:
$ depthchargectl build --board amd64-generic -vvv
[...]
Failed while creating depthcharge image.
Traceback (most recent call last):
[...]
File "/usr/lib/python3/dist-packages/depthcharge_tools/mkdepthcharge.py", line 960, in __call__
with vmlinuz.open("r+b") as f, mmap(f.fileno(), 0) as data:
~~~~^^^^^^^^^^^^^^^
ValueError: cannot mmap an empty file
[...]
Ultimately, it's because `lzma -d` returns a zero exit status for certain
files even though it outputs nothing:
$ head -c18 "/boot/vmlinuz-$(uname -a)" | xxd
00000000: 4d5a 0000 0000 0000 0000 0000 0000 0000 MZ..............
00000010: 0000 ..
$ head -c18 "/boot/vmlinuz-$(uname -a)" | lzma -d; echo $?
0
Check against empty decompression outputs, consider them not compressed
with that scheme, and so continue trying with other decompressors.
We need to remove the newly created empty file so the next compressor
doesn't throw up a FileExistsError.
Signed-off-by: Alper Nebi Yasak <[email protected]>
---
depthcharge_tools/utils/pathlib.py | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/depthcharge_tools/utils/pathlib.py b/depthcharge_tools/utils/pathlib.py
index 4063312cc8cb..ffb5f7ae918a 100644
--- a/depthcharge_tools/utils/pathlib.py
+++ b/depthcharge_tools/utils/pathlib.py
@@ -31,7 +31,13 @@ def decompress(src, dest=None, partial=False):
for runner in (gzip, zstd, xz, lz4, lzma, bzip2, lzop):
try:
- return runner.decompress(src, dest)
+ out = runner.decompress(src, dest)
+ if out in (None, "", b""):
+ continue
+ if isinstance(out, Path) and out.stat().st_size == 0:
+ out.unlink(missing_ok=True)
+ continue
+ return out
except FileNotFoundError:
if dest:
base-commit: 95d17c444ae3a9dec1c51ead6301ed04777314b9
--
2.55.0