1
0
Fork 0
mirror of https://git.tukaani.org/xz.git synced 2024-04-04 12:36:23 +02:00

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.
This commit is contained in:
Lasse Collin 2022-12-08 19:18:16 +02:00
parent 7623b22d1d
commit 4af80d4f51

View file

@ -31,7 +31,7 @@ const char stdin_filename[] = "(stdin)";
/// Parse and set the memory usage limit for compression and/or decompression. /// Parse and set the memory usage limit for compression and/or decompression.
static void 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_compress, bool set_decompress)
{ {
bool is_percentage = false; bool is_percentage = false;
@ -39,9 +39,18 @@ parse_memlimit(const char *name, const char *name_percentage, char *str,
const size_t len = strlen(str); const size_t len = strlen(str);
if (len > 0 && str[len - 1] == '%') { 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; is_percentage = true;
value = str_to_uint64(name_percentage, str, 1, 100); value = str_to_uint64(name_percentage, s, 1, 100);
free(s);
} else { } else {
// On 32-bit systems, SIZE_MAX would make more sense than // On 32-bit systems, SIZE_MAX would make more sense than
// UINT64_MAX. But use UINT64_MAX still so that scripts // UINT64_MAX. But use UINT64_MAX still so that scripts
@ -56,8 +65,12 @@ parse_memlimit(const char *name, const char *name_percentage, char *str,
static void 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. // It must be non-empty and not begin with a comma.
if (str[0] == '\0' || str[0] == ',') if (str[0] == '\0' || str[0] == ',')
message_fatal(_("%s: Invalid argument to --block-list"), str); message_fatal(_("%s: Invalid argument to --block-list"), str);
@ -112,6 +125,8 @@ parse_block_list(char *str)
// Terminate the array. // Terminate the array.
opt_block_list[count] = 0; opt_block_list[count] = 0;
free(str_start);
return; return;
} }