From: Darafei Praliaskouski Date: Thu, 7 May 2026 19:56:38 +0000 (+0400) Subject: options: parse quoted MTR_OPTIONS arguments X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=refs%2Fpull%2F577%2Fhead;p=thirdparty%2Fmtr.git options: parse quoted MTR_OPTIONS arguments --- diff --git a/ui/mtr.c b/ui/mtr.c index 6886bce..6dc535e 100644 --- a/ui/mtr.c +++ b/ui/mtr.c @@ -686,22 +686,63 @@ static void parse_mtr_options( char *string) { int argc = 1; - char *argv[128], *p; + char *argv[128], *arg, *input, *output, *option_string; + int quote; if (!string) return; argv[0] = xstrdup(PACKAGE_NAME); - argc = 1; - p = strtok(string, " \t"); - while (p != NULL && ((size_t) argc < (sizeof(argv) / sizeof(argv[0])))) { - argv[argc++] = p; - p = strtok(NULL, " \t"); + option_string = xstrdup(string); + input = option_string; + output = option_string; + + while ((size_t) argc < (sizeof(argv) / sizeof(argv[0]))) { + while (*input && isspace((unsigned char) *input)) + input++; + if (!*input) + break; + + arg = output; + quote = 0; + while (*input) { + if (quote) { + if (*input == quote) { + input++; + quote = 0; + } else if (*input == '\\' && input[1]) { + input++; + *output++ = *input++; + } else { + *output++ = *input++; + } + } else if (isspace((unsigned char) *input)) { + break; + } else if (*input == '"' || *input == '\'') { + quote = *input++; + } else if (*input == '\\' && input[1]) { + input++; + *output++ = *input++; + } else { + *output++ = *input++; + } + } + + if (quote) { + error(EXIT_FAILURE, 0, "unterminated quote in MTR_OPTIONS"); + } + if (*input && isspace((unsigned char) *input)) { + input++; + } + + *output++ = '\0'; + argv[argc++] = arg; } - if (p != NULL) { - error(0, 0, "Warning: extra arguments ignored: %s", p); + if (*input) { + error(0, 0, "Warning: extra arguments ignored: %s", input); } parse_arg(ctl, names, argc, argv); + free(option_string); free(argv[0]); optind = 0; }