diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/main.c | 96 |
1 files changed, 69 insertions, 27 deletions
diff --git a/src/firejail/main.c b/src/firejail/main.c index 28351a2df..4f1c81e2b 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c | |||
@@ -2009,25 +2009,34 @@ int main(int argc, char **argv) { | |||
2009 | int len = 0; | 2009 | int len = 0; |
2010 | int argcnt = argc - prog_index; | 2010 | int argcnt = argc - prog_index; |
2011 | int j; | 2011 | int j; |
2012 | char *arg, *arg_ptr, *token; | 2012 | bool in_quotes = false; |
2013 | 2013 | ||
2014 | for (i = 0; i < argcnt; i++) { | 2014 | for (i = 0; i < argcnt; i++) { |
2015 | arg = strdup(argv[i + prog_index]); | 2015 | in_quotes = false; |
2016 | arg_ptr = arg; | 2016 | for (j = 0; j < strlen(argv[i + prog_index]); j++) { |
2017 | for (token = strsep(&arg_ptr, "\'"); token != NULL; token = strsep(&arg_ptr, "\'")) { | 2017 | if (argv[i + prog_index][j] == '\'') { |
2018 | if (token[0] == '\0') { | 2018 | if (in_quotes) |
2019 | len += 3; | 2019 | len++; |
2020 | if (j > 0 && argv[i + prog_index][j-1] == '\'') | ||
2021 | len++; | ||
2022 | else | ||
2023 | len += 3; | ||
2024 | in_quotes = false; | ||
2020 | } else { | 2025 | } else { |
2021 | len += strlen(token) + 5; | 2026 | if (!in_quotes) |
2027 | len++; | ||
2028 | len++; | ||
2029 | in_quotes = true; | ||
2022 | } | 2030 | } |
2023 | } | 2031 | } |
2024 | free(arg); | 2032 | if (in_quotes) { |
2025 | len -= 2; // + ' ' - 3 char overrun | 2033 | len++; |
2034 | } | ||
2035 | if (strlen(argv[i + prog_index]) == 0) { | ||
2036 | len += 2; | ||
2037 | } | ||
2038 | len++; | ||
2026 | } | 2039 | } |
2027 | len += 3; // for overrun | ||
2028 | |||
2029 | if (arg_debug) | ||
2030 | printf("Predicted command length %d\n", len); | ||
2031 | 2040 | ||
2032 | // build the string | 2041 | // build the string |
2033 | cfg.command_line = malloc(len + 1); // + '\0' | 2042 | cfg.command_line = malloc(len + 1); // + '\0' |
@@ -2040,31 +2049,64 @@ int main(int argc, char **argv) { | |||
2040 | char *ptr1 = cfg.command_line; | 2049 | char *ptr1 = cfg.command_line; |
2041 | char *ptr2 = cfg.window_title; | 2050 | char *ptr2 = cfg.window_title; |
2042 | for (i = 0; i < argcnt; i++) { | 2051 | for (i = 0; i < argcnt; i++) { |
2052 | |||
2043 | // enclose args by single quotes, | 2053 | // enclose args by single quotes, |
2044 | // and since single quote can't be represented in single quoted text | 2054 | // and since single quote can't be represented in single quoted text |
2045 | // each occurence of it in arg should be enclosed by double quotes | 2055 | // each occurence of it should be enclosed by double quotes |
2046 | arg = strdup(argv[i + prog_index]); | 2056 | in_quotes = false; |
2047 | arg_ptr = arg; | 2057 | for (j = 0; j < strlen(argv[i + prog_index]); j++) { |
2048 | for (token = strsep(&arg_ptr, "\'"); token != NULL; token = strsep(&arg_ptr, "\'")) { | 2058 | // single quote |
2049 | if (token[0] == '\0') { | 2059 | if (argv[i + prog_index][j] == '\'') { |
2050 | sprintf(ptr1, "\"\'\""); | 2060 | if (in_quotes) { |
2051 | } else { | 2061 | // close quotes |
2052 | sprintf(ptr1, "\'%s\'\"\'\"", token); | 2062 | ptr1[0] = '\''; |
2063 | ptr1++; | ||
2064 | } | ||
2065 | // previous char was single quote too | ||
2066 | if (j > 0 && argv[i + prog_index][j-1] == '\'') { | ||
2067 | ptr1--; | ||
2068 | sprintf(ptr1, "\'\""); | ||
2069 | } | ||
2070 | // this first in series | ||
2071 | else | ||
2072 | { | ||
2073 | sprintf(ptr1, "\"\'\""); | ||
2074 | } | ||
2075 | ptr1 += strlen(ptr1); | ||
2076 | in_quotes = false; | ||
2053 | } | 2077 | } |
2078 | // anything other | ||
2079 | else | ||
2080 | { | ||
2081 | if (!in_quotes) { | ||
2082 | // open quotes | ||
2083 | ptr1[0] = '\''; | ||
2084 | ptr1++; | ||
2085 | } | ||
2086 | ptr1[0] = argv[i + prog_index][j]; | ||
2087 | ptr1++; | ||
2088 | in_quotes = true; | ||
2089 | } | ||
2090 | } | ||
2091 | // close quotes | ||
2092 | if (in_quotes) { | ||
2093 | ptr1[0] = '\''; | ||
2094 | ptr1++; | ||
2095 | } | ||
2096 | // handle empty argument case | ||
2097 | if (strlen(argv[i + prog_index]) == 0) { | ||
2098 | sprintf(ptr1, "\'\'"); | ||
2054 | ptr1 += strlen(ptr1); | 2099 | ptr1 += strlen(ptr1); |
2055 | } | 2100 | } |
2056 | free(arg); | 2101 | // add space |
2057 | ptr1 -= 3; | ||
2058 | |||
2059 | sprintf(ptr1, " "); | 2102 | sprintf(ptr1, " "); |
2060 | ptr1 += strlen(ptr1); | 2103 | ptr1 += strlen(ptr1); |
2061 | 2104 | ||
2062 | sprintf(ptr2, "%s ", argv[i + prog_index]); | 2105 | sprintf(ptr2, "%s ", argv[i + prog_index]); |
2063 | ptr2 += strlen(ptr2); | 2106 | ptr2 += strlen(ptr2); |
2064 | } | 2107 | } |
2065 | ptr1[0]='\0'; // just to be sure | 2108 | |
2066 | if (arg_debug) | 2109 | assert(len == strlen(cfg.command_line)); |
2067 | printf("Actual command length %zd\n", strlen(cfg.command_line)); | ||
2068 | } | 2110 | } |
2069 | 2111 | ||
2070 | assert(cfg.command_name); | 2112 | assert(cfg.command_name); |