Commit 1aab7e9c for xz

commit 1aab7e9cab1293c2b8a481ed1beac94da21ef04f
Author: rootvector2 <dxbnaveed.k@gmail.com>
Date:   Thu May 28 12:29:23 2026 +0530

    xz: Fix --files/--files0 usage via XZ_OPT and XZ_DEFAULTS env vars

    If --files=FILELIST or --files0=FILELIST was specified via an enrivonment
    variable, it worked if there were no errors when reading from the file
    FILELIST. However, if an error occurred when reading from FILELIST,
    there was a use-after-free bug when printing the error message because
    the memory containing the string "FILELIST" had been freed.

        printf foo.xz > filelist.txt
        XZ_OPT=--files=filelist.txt xz -l

    Because filelist.txt doesn't end in a newline, the file list is seen as
    invalid/truncated, resulting in an error message like this:

        xz: ????????.txt: Unexpected end of input when reading filenames

    The question marks are because the garbage string is masked using
    tuklib_mask_nonprint(). After this commit, it works:

        xz: filelist.txt: Unexpected end of input when reading filenames

    Co-authored-by: Lasse Collin <lasse.collin@tukaani.org>
    Fixes: https://github.com/tukaani-project/xz/pull/223

diff --git a/src/xz/args.c b/src/xz/args.c
index bc7a5e8b..8a9f98dc 100644
--- a/src/xz/args.c
+++ b/src/xz/args.c
@@ -641,15 +641,20 @@ parse_real(args_info *args, int argc, char **argv)
 				args->files_name = stdin_filename;
 				args->files_file = stdin;
 			} else {
-				args->files_name = optarg;
-				args->files_file = fopen(optarg,
+				// If we are called from parse_environment(),
+				// the memory pointed by optarg will be freed
+				// after we return to parse_environment().
+				// We need to duplicate the string.
+				args->files_name = xstrdup(optarg);
+				args->files_file = fopen(args->files_name,
 						c == OPT_FILES ? "r" : "rb");
 				if (args->files_file == NULL)
 					// TRANSLATORS: This is a translatable
 					// string because French needs a space
 					// before the colon ("%s : %s").
 					message_fatal(_("%s: %s"),
-						tuklib_mask_nonprint(optarg),
+						tuklib_mask_nonprint(
+							args->files_name),
 						strerror(errno));
 			}