From 24e765a099ed615378423a411b36ab156bd08f9a Mon Sep 17 00:00:00 2001 From: Nexory Date: Thu, 22 Oct 2026 00:06:47 +0200 Subject: [PATCH 1/2] cli: --rm skips -t and stdin The manual says that -t neither creates nor removes files, and that --rm deletes the source after a successful compression or decompression. The CLI did not follow it for two cases : - `lz4 -t --rm file.lz4` tested the file, then deleted it. - With stdin as source, the output was complete, but remove("stdin") failed and the command ended with "Remove error : stdin" (exit code 50 when compressing, 45 when decompressing). A file named `stdin` in the working directory would have been deleted. One helper, LZ4IO_mustRemoveSrcFile(), now decides. It answers no in test mode and for stdin, and both remove sites use it : LZ4IO_finishCompressedFile() and LZ4IO_decompressSrcFile(). A regular source file is still removed. --- programs/lz4io.c | 15 +++++++++++++-- tests/test-lz4-basic.sh | 11 +++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/programs/lz4io.c b/programs/lz4io.c index 5d7a162b..36392500 100644 --- a/programs/lz4io.c +++ b/programs/lz4io.c @@ -423,6 +423,17 @@ static int LZ4IO_isStdout(const char* s) return UTIL_sameString(s, stdoutmark); } +/* LZ4IO_mustRemoveSrcFile() : + * `--rm` only applies to a regular source file : + * not in test mode, which removes nothing (see lz4.1.md), + * and not when reading from stdin, which is not a file. */ +static int LZ4IO_mustRemoveSrcFile(const LZ4IO_prefs_t* prefs, const char* srcFileName) +{ + return prefs->removeSrcFile + && !prefs->testMode + && !LZ4IO_isStdin(srcFileName); +} + /* ************************************************************************ ** ** ********************** LZ4 File / Pipe compression ********************* ** @@ -881,7 +892,7 @@ LZ4IO_finishCompressedFile(FILE* srcFile, FILE* dstFile, UTIL_setFileStat(dstFileName, &statbuf); } } - if (io_prefs->removeSrcFile && !srcModified && !srcReplaced) { /* remove source file : --rm */ + if (LZ4IO_mustRemoveSrcFile(io_prefs, srcFileName) && !srcModified && !srcReplaced) { /* remove source file : --rm */ if (remove(srcFileName)) END_PROCESS(50, "Remove error : %s: %s", srcFileName, strerror(errno)); } @@ -2637,7 +2648,7 @@ LZ4IO_decompressSrcFile(unsigned long long* outGenSize, /* Close input */ fclose(finput); - if (!result && prefs->removeSrcFile) { /* --rm */ + if (!result && LZ4IO_mustRemoveSrcFile(prefs, input_filename)) { /* --rm */ if (remove(input_filename)) END_PROCESS(45, "Remove error : %s: %s", input_filename, strerror(errno)); } diff --git a/tests/test-lz4-basic.sh b/tests/test-lz4-basic.sh index 4fc411dc..125b680c 100755 --- a/tests/test-lz4-basic.sh +++ b/tests/test-lz4-basic.sh @@ -80,6 +80,17 @@ printf '\120\052\115\030\000\000\000\000BAD!' > $FPREFIX-bad.lz4 cp $FPREFIX-bad.lz4 $FPREFIX-bad-before.lz4 lz4 -d --rm -f $FPREFIX-bad.lz4 $FPREFIX-bad.out && exit 1 diff -q $FPREFIX-bad-before.lz4 $FPREFIX-bad.lz4 # --rm keeps source after decoding failure +echo "rm test" > $FPREFIX-rm +lz4 $FPREFIX-rm $FPREFIX-rm.lz4 +cp $FPREFIX-rm.lz4 $FPREFIX-rm-before.lz4 +lz4 -t --rm $FPREFIX-rm.lz4 +diff -q $FPREFIX-rm-before.lz4 $FPREFIX-rm.lz4 # -t --rm keeps its input ("No files are created nor removed") +lz4 -t --rm < $FPREFIX-rm.lz4 # nothing to remove when reading stdin +lz4 -c --rm < $FPREFIX-rm | lz4 -t # idem when compressing +lz4 -dc --rm < $FPREFIX-rm.lz4 | diff -q - $FPREFIX-rm # idem when decompressing +lz4 -d --rm $FPREFIX-rm.lz4 $FPREFIX-rm-out +test ! -f $FPREFIX-rm.lz4 # --rm still removes a regular source file +test -f $FPREFIX-rm-out lz4 -BX $FPREFIX-hw -c -q | lz4 -tv # test block checksum # datagen -g20KB generates the same file every single time # cannot save output of datagen -g20KB as input file to lz4 because the following shell commands are run before datagen -g20KB From ab7ec87f26654b09a9577197237de3ae3909ac09 Mon Sep 17 00:00:00 2001 From: Yann Collet Date: Thu, 22 Oct 2026 16:09:26 -0700 Subject: [PATCH 2/2] NEWS: --rm skips -t and stdin --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index f4cab704..3a054c94 100644 --- a/NEWS +++ b/NEWS @@ -56,6 +56,7 @@ cli : output buffer no longer grows with the nb of threads : more threads withi cli : a source file modified, renamed or replaced during its compression is detected, and kept with `--rm` ; error 54 when the output can't be verified cli : `lz4 -l` could hang on Windows with an empty input, as could decoding the resulting legacy stream cli : `--rm` keeps the source file after a decompression failure, by @Furan666 +cli : `lz4 -t --rm` no longer removes the tested file, and `--rm` with `stdin` no longer fails nor removes a file named `stdin`, by @Nexory cli : `lz4 -t -m` no longer writes decoded content to stdout, reported by @tansy cli : `lz4 --list` rejects truncated frames, instead of reporting them as valid, by @jmestwa-coder cli : numeric arguments that overflow are rejected, instead of silently wrapping around, by @akashdeshmukh-git