From: Kevin Day Date: Sat, 17 Apr 2021 04:00:00 +0000 (-0500) Subject: Bugfix: fll_execute does not execute full path. X-Git-Tag: 0.5.3~40 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=c1c64aa9f7eec584f03306482281bf5c1422d44b;p=fll Bugfix: fll_execute does not execute full path. When passed a full path to a program (rather than depending on detecting in from just a program name) the program does not execute. There are several logic flaws and mistakes. - The last_slash should have "+1" to avoid including the slash itself. - When environment is cleared, it need to potentially use "program" or "arguments.array[0].string" if a slash already exists in the provided name. - The final NULL at the end of the program_path string is missing. - The "program" or "arguments.array[0].string" should be used in general instead of always the "program" only. - The fixated_is is being used incorrectly in private_fll_execute_path_arguments_fixate (and the documentation is incorrect). I suspect that these functions are messy due to changes in design that were not fully updated (including the appropriate documentation). --- diff --git a/level_2/fll_execute/c/execute.c b/level_2/fll_execute/c/execute.c index 5d9565b..8944a91 100644 --- a/level_2/fll_execute/c/execute.c +++ b/level_2/fll_execute/c/execute.c @@ -140,15 +140,15 @@ extern "C" { f_string_t fixed_arguments[arguments.used + 2]; const f_string_t last_slash = strrchr(program ? program : arguments.array[0].string, f_path_separator_s[0]); - const f_array_length_t name_size = last_slash ? strnlen(last_slash, f_path_length_max) : strnlen(program ? program : arguments.array[0].string, f_path_length_max); + const f_array_length_t name_size = last_slash ? strnlen(last_slash + 1, f_path_length_max) : strnlen(program ? program : arguments.array[0].string, f_path_length_max); char program_name[name_size + 1]; program_name[name_size] = 0; - private_fll_execute_path_arguments_fixate(last_slash ? last_slash : program ? program : arguments.array[0].string, arguments, !program, name_size, program_name, fixed_arguments); + private_fll_execute_path_arguments_fixate(program ? program : arguments.array[0].string, arguments, last_slash, !program, name_size, program_name, fixed_arguments); - const int code = option & fl_execute_parameter_option_path ? execv(program, fixed_arguments) : execvp(program, fixed_arguments); + const int code = option & fl_execute_parameter_option_path ? execv(program ? program : arguments.array[0].string, fixed_arguments) : execvp(program ? program : arguments.array[0].string, fixed_arguments); // generally this does not return, but in some cases (such as with scripts) this does return so handle the results. if (result) { @@ -178,87 +178,104 @@ extern "C" { f_string_t fixed_arguments[arguments.used + 2]; const f_string_t last_slash = strrchr(program ? program : arguments.array[0].string, f_path_separator_s[0]); - const f_array_length_t name_size = last_slash ? strnlen(last_slash, f_path_length_max) : strnlen(program ? program : arguments.array[0].string, f_path_length_max); + const f_array_length_t size_name = last_slash ? strnlen(last_slash + 1, f_path_length_max) : strnlen(program ? program : arguments.array[0].string, f_path_length_max); - char program_name[name_size + 1]; - - program_name[name_size] = 0; + char program_name[size_name + 1]; - private_fll_execute_path_arguments_fixate(last_slash ? last_slash : program ? program : arguments.array[0].string, arguments, !program, name_size, program_name, fixed_arguments); + private_fll_execute_path_arguments_fixate(program ? program : arguments.array[0].string, arguments, last_slash, !program, size_name, program_name, fixed_arguments); // when the environment is to be cleared, a full path must be used. if (parameter && !(parameter->option & fl_execute_parameter_option_path) && parameter->environment) { f_string_dynamic_t path = f_string_dynamic_t_initialize; f_string_dynamics_t paths = f_string_dynamics_t_initialize; + f_string_dynamic_t *found = 0; - f_status_t status = f_environment_get(f_path_environment_s, &path); + f_status_t status = F_none; - if (F_status_is_error(status)) { + if (last_slash) { + status = f_file_exists(program ? program : arguments.array[0].string); - // Do not consider PATH is not available (or valid?) to be an error. - if (F_status_set_fine(status) == F_valid_not || F_status_set_fine(status) == F_failure) { - status = F_none; + if (status != F_true) { + f_macro_string_dynamics_t_delete_simple(paths); + + return F_status_set_error(F_file_found_not); } + + path.string = program ? program : arguments.array[0].string; + path.used = strnlen(program ? program : arguments.array[0].string, f_path_length_max); + found = &path; } else { - status = fl_environment_path_explode_dynamic(path, &paths); - } + status = f_environment_get(f_path_environment_s, &path); - f_macro_string_dynamic_t_delete_simple(path); - - if (F_status_is_error(status)) { - f_macro_string_dynamics_t_delete_simple(paths); - return status; - } + if (F_status_is_error(status)) { - f_string_dynamic_t *found = 0; + // Do not consider PATH is not available (or valid?) to be an error. + if (F_status_set_fine(status) == F_valid_not || F_status_set_fine(status) == F_failure) { + status = F_none; + } + } + else { + status = fl_environment_path_explode_dynamic(path, &paths); + } - for (f_array_length_t i = 0; i < paths.used; i++) { + f_macro_string_dynamic_t_delete_simple(path); - status = f_string_append(program_name, name_size, &paths.array[i]); + if (F_status_is_error(status)) { + f_macro_string_dynamics_t_delete_simple(paths); - if (F_status_is_error_not(status)) { - status = f_string_dynamic_terminate(&paths.array[i]); + return status; } - if (F_status_is_error_not(status)) { - status = f_file_exists(paths.array[i].string); + for (f_array_length_t i = 0; i < paths.used; ++i) { - if (status == F_true) { - found = &paths.array[i]; - break; + status = f_string_append(program_name, size_name, &paths.array[i]); + + if (F_status_is_error_not(status)) { + status = f_string_dynamic_terminate_after(&paths.array[i]); } - if (F_status_is_error(status)) { - status = F_status_set_fine(status); + if (F_status_is_error_not(status)) { + status = f_file_exists(paths.array[i].string); - // don't consider bad/non-accessible paths an error, just ignore them. - if (status == F_name) { - continue; - } - else if (status == F_directory) { - continue; + if (status == F_true) { + found = &paths.array[i]; + + break; } - else if (status == F_access_denied) { - continue; + + if (F_status_is_error(status)) { + status = F_status_set_fine(status); + + // don't consider bad/non-accessible paths an error, just ignore them. + if (status == F_name) { + continue; + } + else if (status == F_directory) { + continue; + } + else if (status == F_access_denied) { + continue; + } } } - } - if (F_status_is_error(status)) { - f_macro_string_dynamics_t_delete_simple(paths); + if (F_status_is_error(status)) { + f_macro_string_dynamics_t_delete_simple(paths); - return status; - } - } // for + return status; + } + } // for - if (!found) { - f_macro_string_dynamics_t_delete_simple(paths); + if (!found) { + f_macro_string_dynamics_t_delete_simple(paths); - return F_status_set_error(F_file_found_not); + return F_status_set_error(F_file_found_not); + } } - char program_path[found->used]; + char program_path[found->used + 1]; + program_path[found->used] = 0; memcpy(&program_path, found->string, found->used); @@ -273,10 +290,10 @@ extern "C" { } if (parameter && parameter->data) { - return private_fll_execute_fork_data(program, fixed_arguments, parameter, as, result); + return private_fll_execute_fork_data(program ? program : arguments.array[0].string, fixed_arguments, parameter, as, result); } - return private_fll_execute_fork(program, fixed_arguments, parameter, as, result); + return private_fll_execute_fork(program ? program : arguments.array[0].string, fixed_arguments, parameter, as, result); } #endif // _di_fll_execute_program_ diff --git a/level_2/fll_execute/c/execute.h b/level_2/fll_execute/c/execute.h index 702f98c..9c88259 100644 --- a/level_2/fll_execute/c/execute.h +++ b/level_2/fll_execute/c/execute.h @@ -356,7 +356,7 @@ extern "C" { * * @param program * The name or path of the program. - * The string pointer may be set to 0, to designate that the first index in arguments is assumed to be the program. + * Set to NULL, to designate that arguments[0] is the program name or path. * @param arguments * An array of strings representing the arguments. * @param option @@ -405,7 +405,7 @@ extern "C" { * * @param program * The name or path of the program. - * The string pointer may be set to 0, to designate that the first index in arguments is assumed to be the program. + * Set to NULL, to designate that arguments[0] is the program name or path. * @param arguments * An array of strings representing the arguments. * @param parameter @@ -462,7 +462,7 @@ extern "C" { * Errors (with error bit) from: fl_environment_path_explode_dynamic(). * Errors (with error bit) from: f_string_append(). * Errors (with error bit) from: f_string_dynamic_delete(). - * Errors (with error bit) from: f_string_dynamic_terminate(). + * Errors (with error bit) from: f_string_dynamic_terminate_after(). * * @see close() * @see clearenv() diff --git a/level_2/fll_execute/c/private-execute.c b/level_2/fll_execute/c/private-execute.c index 76bafd0..19c771b 100644 --- a/level_2/fll_execute/c/private-execute.c +++ b/level_2/fll_execute/c/private-execute.c @@ -594,35 +594,26 @@ extern "C" { #endif // !defined(_di_fll_execute_program_) #if !defined(_di_fll_execute_program_) - void private_fll_execute_path_arguments_fixate(const f_string_t program_path, const f_string_statics_t arguments, const bool fixated_is, const f_array_length_t name_size, char program_name[], f_string_t fixed_arguments[]) { + void private_fll_execute_path_arguments_fixate(const f_string_t program_path, const f_string_statics_t arguments, const f_string_t last_slash, const bool fixated_is, const f_array_length_t name_size, char program_name[], f_string_t fixed_arguments[]) { - memcpy(program_name, program_path, name_size); - program_name[name_size] = 0; + memset(program_name, 0, name_size + 1); + memset(fixed_arguments, 0, sizeof(f_string_t) * (arguments.used + 2)); + memcpy(program_name, last_slash ? last_slash + 1 : program_path, name_size); if (name_size) { fixed_arguments[0] = program_name; } - else { - fixed_arguments[0] = 0; - } - - f_array_length_t i = 0; if (fixated_is) { - for (i = 1; i < arguments.used; ++i) { + for (f_array_length_t i = 1; i < arguments.used; ++i) { fixed_arguments[i] = arguments.array[i].string; } // for } else { - for (; i < arguments.used; ++i) { + for (f_array_length_t i = 0; i < arguments.used; ++i) { fixed_arguments[i + 1] = arguments.array[i].string; } // for - - i++; } - - // insert the required end of array designator. - fixed_arguments[i] = 0; } #endif // !defined(_di_fll_execute_program_) diff --git a/level_2/fll_execute/c/private-execute.h b/level_2/fll_execute/c/private-execute.h index 55e6b85..9d73114 100644 --- a/level_2/fll_execute/c/private-execute.h +++ b/level_2/fll_execute/c/private-execute.h @@ -319,12 +319,15 @@ extern "C" { * Private function for reconstructing the arguments into a fixed array. * * @param program_path - * The part of the path to the program representing the program name to copy from. + * The full path to the program or the program name to copy from. * @param arguments * An array of strings representing the arguments. + * @param last_slash + * A pointer to the last slash. + * Set to NULL if there is no slash in the program_path. * @param fixated_is - * If TRUE, then this is a path to a program (such as "/bin/bash"). - * If FALSE, then this is not a path to a program (such as "bash"). + * If TRUE, then the program_path is already fixated in the fixed_arguments at index 0. + * If FALSE, then the program_path needs to be fixated in the fixed_arguments at index 0. * @param name_size * The size of the program_path to copy. * @param program_name @@ -338,7 +341,7 @@ extern "C" { * @see fll_execute_program() */ #if !defined(_di_fll_execute_program_) - extern void private_fll_execute_path_arguments_fixate(const f_string_t program_path, const f_string_statics_t arguments, const bool fixated_is, const f_array_length_t name_size, char program_name[], f_string_t fixed_arguments[]) f_gcc_attribute_visibility_internal; + extern void private_fll_execute_path_arguments_fixate(const f_string_t program_path, const f_string_statics_t arguments, const f_string_t last_slash, const bool fixated_is, const f_array_length_t name_size, char program_name[], f_string_t fixed_arguments[]) f_gcc_attribute_visibility_internal; #endif // !defined(_di_fll_execute_program_) #ifdef __cplusplus