summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2022-12-08 19:18:16 +0200
committerLasse Collin <lasse.collin@tukaani.org>2022-12-08 19:18:16 +0200
commitbc665b84ea6bf7946394a08122177efe41b26a5f (patch)
treea9c5f64e1692ade3b842fa82c9e4a01abc37cb11
parenta13064e1c290de7933db72b6dffbd65cfce59c9f (diff)
downloadxz-bc665b84ea6bf7946394a08122177efe41b26a5f.tar.gz
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.
-rw-r--r--src/xz/args.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/xz/args.c b/src/xz/args.c
index 8953aa5..3d09bd6 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;
}