]> Kevux Git Server - fll/commitdiff
Bugfix: fll_execute does not execute full path.
authorKevin Day <thekevinday@gmail.com>
Sat, 17 Apr 2021 04:00:00 +0000 (23:00 -0500)
committerKevin Day <thekevinday@gmail.com>
Sat, 17 Apr 2021 04:08:32 +0000 (23:08 -0500)
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).

level_2/fll_execute/c/execute.c
level_2/fll_execute/c/execute.h
level_2/fll_execute/c/private-execute.c
level_2/fll_execute/c/private-execute.h

index 5d9565b47b1f717df84b9d99c09896a422b0a24a..8944a91ba1ab0b8b8609f804590f8a6f51073d85 100644 (file)
@@ -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_
 
index 702f98c3f61be1dd9f05b2793b23ee7ead7dfb67..9c882595e6e3bfe43cd680fdd925c632ca778674 100644 (file)
@@ -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()
index 76bafd0901135c000a66d5271f80f9f12afabf4f..19c771b289934f239a26baa45db9d72b634062ae 100644 (file)
@@ -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_)
 
index 55e6b85cd7f64cea10d6f50665e3a26d61c9db0a..9d73114a0df398d2c9cf73ec418496830bf8a528 100644 (file)
@@ -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