authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2022-08-13 22:08:40-07:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-08-15 11:25:51+03:00
log764cf4e53ffc29bbd39c636020019ae419135d82
tree694f59466e8c09fde25f31a510c449914f9f5b47
parent2279f27e0f97e66aedc87ec5c85f05b185a3631d

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`.

2 files changed, 7 insertions(+), 2 deletions(-)

lib/std/fs.zig+4-2
...@@ -877,8 +877,9 @@ pub const IterableDir = struct {...@@ -877,8 +877,9 @@ pub const IterableDir = struct {
877 /// a reference to the path.877 /// a reference to the path.
878 pub fn next(self: *Walker) !?WalkerEntry {878 pub fn next(self: *Walker) !?WalkerEntry {
879 while (self.stack.items.len != 0) {879 while (self.stack.items.len != 0) {
880 // `top` becomes invalid after appending to `self.stack`880 // `top` and `containing` become invalid after appending to `self.stack`
881 var top = &self.stack.items[self.stack.items.len - 1];881 var top = &self.stack.items[self.stack.items.len - 1];
882 var containing = top;
882 var dirname_len = top.dirname_len;883 var dirname_len = top.dirname_len;
883 if (try top.iter.next()) |base| {884 if (try top.iter.next()) |base| {
884 self.name_buffer.shrinkRetainingCapacity(dirname_len);885 self.name_buffer.shrinkRetainingCapacity(dirname_len);
...@@ -899,10 +900,11 @@ pub const IterableDir = struct {...@@ -899,10 +900,11 @@ pub const IterableDir = struct {
899 .dirname_len = self.name_buffer.items.len,900 .dirname_len = self.name_buffer.items.len,
900 });901 });
901 top = &self.stack.items[self.stack.items.len - 1];902 top = &self.stack.items[self.stack.items.len - 1];
903 containing = &self.stack.items[self.stack.items.len - 2];
902 }904 }
903 }905 }
904 return WalkerEntry{906 return WalkerEntry{
905 .dir = top.iter.dir,907 .dir = containing.iter.dir,
906 .basename = self.name_buffer.items[dirname_len..],908 .basename = self.name_buffer.items[dirname_len..],
907 .path = self.name_buffer.items,909 .path = self.name_buffer.items,
908 .kind = base.kind,910 .kind = base.kind,
lib/std/fs/test.zig+3
...@@ -1058,6 +1058,9 @@ test "walker" {...@@ -1058,6 +1058,9 @@ test "walker" {
1058 std.debug.print("found unexpected path: {s}\n", .{std.fmt.fmtSliceEscapeLower(entry.path)});1058 std.debug.print("found unexpected path: {s}\n", .{std.fmt.fmtSliceEscapeLower(entry.path)});
1059 return err;1059 return err;
1060 };1060 };
1061 // make sure that the entry.dir is the containing dir
1062 var entry_dir = try entry.dir.openDir(entry.basename, .{});
1063 defer entry_dir.close();
1061 num_walked += 1;1064 num_walked += 1;
1062 }1065 }
1063 try testing.expectEqual(expected_paths.kvs.len, num_walked);1066 try testing.expectEqual(expected_paths.kvs.len, num_walked);