]> Kevux Git Server - fll/commitdiff
Regression: Parent directory in recursion does not get processed properly.
authorKevin Day <Kevin@kevux.org>
Sun, 13 Apr 2025 02:20:42 +0000 (21:20 -0500)
committerKevin Day <Kevin@kevux.org>
Sun, 13 Apr 2025 02:24:48 +0000 (21:24 -0500)
The commit 8df0301badf6f38fcb4ddf73318e02708ad344f7 fixed a problem with the parent directory not being processed at all.
It failed to handle the situation where the child directory alters the path to append itself.

Save the parent directory path and then restore it after processing the child directory.

Many POSIX libc functions work on NULL termination where possible.
Make sure a NULL termination exists after restoring the path.

level_1/fl_directory/c/private-directory.c

index fc17ce221b488458c028375c55953df10c8c317d..9b2265492e8724712cc9ba2631920ff33d073e3f 100644 (file)
@@ -62,6 +62,7 @@ extern "C" {
     f_number_unsigned_t i = 0;
     uint8_t j = 0;
     const f_number_unsigned_t used_original = recurse->path.used;
+    f_number_unsigned_t used_directory = 0;
 
     static const uint32_t flag_actions[] = {
       f_directory_recurse_do_flag_before_e,
@@ -170,6 +171,7 @@ extern "C" {
 
         // Guarantee NULL termination.
         recurse->path.string[recurse->path.used] = 0;
+        used_directory = recurse->path.used;
 
         if (F_status_is_error_not(recurse->state.status)) {
           recurse->state.status = f_directory_exists(recurse->path);
@@ -203,6 +205,10 @@ extern "C" {
             // This loop is not considered a loop for breaking and continuing.
             if (recurse->state.status == F_break || recurse->state.status == F_done || recurse->state.status == F_continue || F_status_set_fine(recurse->state.status) == F_interrupt) break;
 
+            // Reset the path after operating on child directories.
+            recurse->path.used = used_directory;
+            recurse->path.string[recurse->path.used] = 0;
+
             recurse->action(recurse, recurse->listing.directory.array[i], f_directory_recurse_do_flag_action_e | f_directory_recurse_do_flag_directory_e);
 
             if (F_status_is_error(recurse->state.status)) {
@@ -234,6 +240,10 @@ extern "C" {
 
     recurse->path.used = used_original;
 
+    if (recurse->path.used < recurse->path.size) {
+      recurse->path.string[recurse->path.used] = 0;
+    }
+
     // Only the directory is to be freed because all others are preserved between recursions.
     f_memory_arrays_resize(0, sizeof(f_string_dynamic_t), (void **) &recurse->listing.directory.array, &recurse->listing.directory.used, &recurse->listing.directory.size, &f_string_dynamics_delete_callback);