diff options
author | Lasse Collin <lasse.collin@tukaani.org> | 2022-12-08 19:18:16 +0200 |
---|---|---|
committer | Lasse Collin <lasse.collin@tukaani.org> | 2022-12-08 19:18:16 +0200 |
commit | bc665b84ea6bf7946394a08122177efe41b26a5f (patch) | |
tree | a9c5f64e1692ade3b842fa82c9e4a01abc37cb11 /src/xz | |
parent | Translations: Update the German man page translations. (diff) | |
download | xz-bc665b84ea6bf7946394a08122177efe41b26a5f.tar.xz |
xz: Don't modify argv[].
The code that parses --memlimit options and --block-list modified
the argv[] when parsing the option string from optarg. This was
visible in "ps auxf" and such and could be confusing. I didn't
understand it back in the day when I wrote that code. Now a copy
is allocated when modifiable strings are needed.
Diffstat (limited to 'src/xz')
-rw-r--r-- | src/xz/args.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/xz/args.c b/src/xz/args.c index 8953aa59..3d09bd64 100644 --- a/src/xz/args.c +++ b/src/xz/args.c @@ -32,7 +32,7 @@ const char stdin_filename[] = "(stdin)"; /// Parse and set the memory usage limit for compression, decompression, /// and/or multithreaded decompression. static void -parse_memlimit(const char *name, const char *name_percentage, char *str, +parse_memlimit(const char *name, const char *name_percentage, const char *str, bool set_compress, bool set_decompress, bool set_mtdec) { bool is_percentage = false; @@ -40,9 +40,18 @@ parse_memlimit(const char *name, const char *name_percentage, char *str, const size_t len = strlen(str); if (len > 0 && str[len - 1] == '%') { - str[len - 1] = '\0'; + // Make a copy so that we can get rid of %. + // + // In the past str wasn't const and we modified it directly + // but that modified argv[] and thus affected what was visible + // in "ps auxf" or similar tools which was confusing. For + // example, --memlimit=50% would show up as --memlimit=50 + // since the percent sign was overwritten here. + char *s = xstrdup(str); + s[len - 1] = '\0'; is_percentage = true; - value = str_to_uint64(name_percentage, str, 1, 100); + value = str_to_uint64(name_percentage, s, 1, 100); + free(s); } else { // On 32-bit systems, SIZE_MAX would make more sense than // UINT64_MAX. But use UINT64_MAX still so that scripts @@ -57,8 +66,12 @@ parse_memlimit(const char *name, const char *name_percentage, char *str, static void -parse_block_list(char *str) +parse_block_list(const char *str_const) { + // We need a modifiable string in the for-loop. + char *str_start = xstrdup(str_const); + char *str = str_start; + // It must be non-empty and not begin with a comma. if (str[0] == '\0' || str[0] == ',') message_fatal(_("%s: Invalid argument to --block-list"), str); @@ -113,6 +126,8 @@ parse_block_list(char *str) // Terminate the array. opt_block_list[count] = 0; + + free(str_start); return; } |