Commit 764cf4e53f

Ryan Liptak <squeek502@hotmail.com>
2022-08-14 07:08:40
std.fs: Fix `WalkerEntry.dir` not always being the containing dir
Before this commit, the modified test would fail with `FileNotFound` because the `entry.dir` would be for the entry itself rather than the containing dir of the entry. That is, if you were walking a tree of `a/b`, then (previously) the entry for `b` would incorrectly have an `entry.dir` for `b` rather than `a`.
1 parent 2279f27
Changed files (2)
lib
lib/std/fs/test.zig
@@ -1058,6 +1058,9 @@ test "walker" {
             std.debug.print("found unexpected path: {s}\n", .{std.fmt.fmtSliceEscapeLower(entry.path)});
             return err;
         };
+        // make sure that the entry.dir is the containing dir
+        var entry_dir = try entry.dir.openDir(entry.basename, .{});
+        defer entry_dir.close();
         num_walked += 1;
     }
     try testing.expectEqual(expected_paths.kvs.len, num_walked);
lib/std/fs.zig
@@ -877,8 +877,9 @@ pub const IterableDir = struct {
         /// a reference to the path.
         pub fn next(self: *Walker) !?WalkerEntry {
             while (self.stack.items.len != 0) {
-                // `top` becomes invalid after appending to `self.stack`
+                // `top` and `containing` become invalid after appending to `self.stack`
                 var top = &self.stack.items[self.stack.items.len - 1];
+                var containing = top;
                 var dirname_len = top.dirname_len;
                 if (try top.iter.next()) |base| {
                     self.name_buffer.shrinkRetainingCapacity(dirname_len);
@@ -899,10 +900,11 @@ pub const IterableDir = struct {
                                 .dirname_len = self.name_buffer.items.len,
                             });
                             top = &self.stack.items[self.stack.items.len - 1];
+                            containing = &self.stack.items[self.stack.items.len - 2];
                         }
                     }
                     return WalkerEntry{
-                        .dir = top.iter.dir,
+                        .dir = containing.iter.dir,
                         .basename = self.name_buffer.items[dirname_len..],
                         .path = self.name_buffer.items,
                         .kind = base.kind,