commit: 1fcf8f53423288232b6c3ea15c1e288b62fabbba
Author: Kerin Millar <kfm <AT> plushkava <DOT> net>
AuthorDate: Wed Jun 25 00:58:29 2025 +0000
Commit: Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sat Jun 28 02:30:15 2025 +0000
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=1fcf8f53
ecompress-file: correctly delete compressed files in compress_file()
Presently, the compress_file() function contains a command whose purpose
is to delete any existing, compressed instances of the files whose names
are defined by the positional parameters. It employs a pattern-replacing
parameter expansion, transforming the positional parameters in such a
way that the value of the 'PORTAGE_COMPRESS_SUFFIX' variable is appended
to each of the resulting words.
However, it also appends the <SOH> character to each word, ostensibly
for the purpose of being treated as a pathname terminator. To do so is
fundamentally incorrect, since all bytes are legal in pathname
components, save for <slash> and the null byte.
What's more, the resulting words are conveyed to the echo builtin,
whereupon they are joined by a <space> into a single stream. This stream
then undergoes a transformation whereby <SOH> is replaced by the null
byte. Finally, the resulting stream is conveyed to xargs(1) for reading.
Put simply, the code is poppycock. Consider the following.
$ set -- foo bar baz
$ touch "$@"
$ echo -n "${@/%/$'\001'}" | tr '\001' '\000' | xargs -0 rm
rm: cannot remove ' bar': No such file or directory
rm: cannot remove ' baz': No such file or directory
The correct way to write the above would be as follows.
$ printf '%s\0' "$@" | xargs -0 rm --
This commit addresses the aforementioned defects in the manner
described. Namely, by using the printf builtin to produce a stream of
null-terminated pathnames that is directly consumed by xargs(1).
Further, the "--" operand is passed to rm(1) to signify end-of-options.
Signed-off-by: Kerin Millar <kfm <AT> plushkava.net>
Signed-off-by: Sam James <sam <AT> gentoo.org>
bin/ecompress-file | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/bin/ecompress-file b/bin/ecompress-file
index a1009c0289..2916ecf171 100755
--- a/bin/ecompress-file
+++ b/bin/ecompress-file
@@ -44,8 +44,10 @@ compress_file() {
# If a compressed version of the file already exists, simply
# delete it so that the compressor doesn't whine (bzip2 will
# complain and skip, gzip will prompt for input)
- [[ -n ${PORTAGE_COMPRESS_SUFFIX} ]] && echo -n
"${@/%/${PORTAGE_COMPRESS_SUFFIX}$'\001'}" | \
- tr '\001' '\000' | ${XARGS} -0 rm -f
+ if [[ ${PORTAGE_COMPRESS_SUFFIX} ]]; then
+ printf '%s\0' "${@/%/${PORTAGE_COMPRESS_SUFFIX}}" \
+ | ${XARGS} -0 rm -f --
+ fi
# forcibly break all hard links as some compressors whine about it
while IFS= read -d '' -r x ; do