From d414d50af62ed54ac689017ff59dd0d58feb34f9 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sun, 17 Jul 2022 15:34:16 -0500 Subject: [PATCH] Bugfix: Reserved parameter IKI expansion is not adding spaces and the "top" reserved parameter should always end in a slash. The IKI expansion on reserved parameters, such as "parameter:"fakefile"", should include spaces as appropriate. For example, given a call to "fake -f my_fakefile", the parameter:"fakefile" should expand into "-f my_fakefile" but is instead expanding into "-fmy_fakefile". For security reasons, the expanded paths, such as parameter:"top", should always have a trailing slash. Consider "rm -Rf parameter:"top"tmp" vs "rm -Rf parameter:"top"/tmp". On the left side, if parameter:"top" resolves into an empty string, then the command is: "rm -Rf tmp". On the right side, if parameter:"top" resolves into an empty string, then the command is: "rm -Rf /tmp". The right side would end up destroying a path outside of the project root, such as "/tmp"! --- level_3/fake/c/private-make-operate.c | 85 +++++++++++++++++++++-------------- level_3/fake/documents/fakefile.txt | 2 +- 2 files changed, 52 insertions(+), 35 deletions(-) diff --git a/level_3/fake/c/private-make-operate.c b/level_3/fake/c/private-make-operate.c index edbbf99..f1fe027 100644 --- a/level_3/fake/c/private-make-operate.c +++ b/level_3/fake/c/private-make-operate.c @@ -368,6 +368,14 @@ extern "C" { data_make->cache_arguments.array[data_make->cache_arguments.used].used = 0; if (data_make->path.stack.used) { + *status = f_string_dynamic_increase_by(data_make->path.stack.array[0].used + f_path_separator_s.used + 1, &data_make->cache_arguments.array[data_make->cache_arguments.used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_increase_by", F_true); + + break; + } + *status = f_string_dynamic_append(data_make->path.stack.array[0], &data_make->cache_arguments.array[data_make->cache_arguments.used]); if (F_status_is_error(*status)) { @@ -375,6 +383,15 @@ extern "C" { break; } + + // For safe path handling, always append the trailing slash. + *status = f_string_dynamic_append(f_path_separator_s, &data_make->cache_arguments.array[data_make->cache_arguments.used]); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); + + break; + } } unmatched = F_false; @@ -423,15 +440,29 @@ extern "C" { if (!reserved_value[k]->array[l].used) continue; if (separate) { - *status = f_string_dynamic_append(f_string_space_s, &data_make->cache_arguments.array[data_make->cache_arguments.used]); + if (quotes.array[i]) { + *status = f_string_dynamic_append(f_string_space_s, &data_make->cache_arguments.array[data_make->cache_arguments.used]); - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append", F_true); - break; + break; + } + } + + // Unquoted use separate parameters rather then being separated by a space. + else { + ++data_make->cache_arguments.used; + + *status = f_string_dynamics_increase(fake_default_allocation_small_d, &data_make->cache_arguments); + + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamics_increase", F_true); + + break; + } } - separate = F_false; } *status = f_string_dynamic_append_nulless(reserved_value[k]->array[l], &data_make->cache_arguments.array[data_make->cache_arguments.used]); @@ -441,6 +472,8 @@ extern "C" { break; } + + separate = F_true; } // for } @@ -462,12 +495,12 @@ extern "C" { separate = F_false; if (parameter->array[k].value.used) { - if (quotes.array[i]) { - for (l = 0; l < parameter->array[k].value.used; ++l) { + for (l = 0; l < parameter->array[k].value.used; ++l) { - if (!parameter->array[k].value.array[l].used) continue; + if (!parameter->array[k].value.array[l].used) continue; - if (separate) { + if (separate) { + if (quotes.array[i]) { *status = f_string_dynamic_append(f_string_space_s, &data_make->cache_arguments.array[data_make->cache_arguments.used]); if (F_status_is_error(*status)) { @@ -477,24 +510,8 @@ extern "C" { } } - *status = f_string_dynamic_append_nulless(parameter->array[k].value.array[l], &data_make->cache_arguments.array[data_make->cache_arguments.used]); - - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); - - break; - } - - separate = F_true; - } // for - } - else { - for (l = 0; l < parameter->array[k].value.used; ++l) { - - if (!parameter->array[k].value.array[l].used) continue; - // Unquoted use separate parameters rather then being separated by a space. - if (separate) { + else { ++data_make->cache_arguments.used; *status = f_string_dynamics_increase(fake_default_allocation_small_d, &data_make->cache_arguments); @@ -505,18 +522,18 @@ extern "C" { break; } } + } - *status = f_string_dynamic_append_nulless(parameter->array[k].value.array[l], &data_make->cache_arguments.array[data_make->cache_arguments.used]); + *status = f_string_dynamic_append_nulless(parameter->array[k].value.array[l], &data_make->cache_arguments.array[data_make->cache_arguments.used]); - if (F_status_is_error(*status)) { - fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); + if (F_status_is_error(*status)) { + fll_error_print(data_make->error, F_status_set_fine(*status), "f_string_dynamic_append_nulless", F_true); - break; - } + break; + } - separate = F_true; - } // for - } + separate = F_true; + } // for if (F_status_is_error(*status)) break; } diff --git a/level_3/fake/documents/fakefile.txt b/level_3/fake/documents/fakefile.txt index 7096a8f..3255fdf 100644 --- a/level_3/fake/documents/fakefile.txt +++ b/level_3/fake/documents/fakefile.txt @@ -321,7 +321,7 @@ Fakefile Documentation: - return: Contains the return value of a previous operation that produces a return code. - settings: Associated with -s/--settings parameter. - sources: Associated with -S/--sources parameter. - - top: The absolute path to the "top" directory, which is the base project directory. + - top: The absolute path to the "top" directory, which is the base project directory (Always has a trailing forward slash). - verbosity: Associated with +Q/++quiet, +E/++error, +N/++normal, +V/++verbose, and +D/++debug parameters. - work: Associated with -w/--work parameter. -- 1.8.3.1