authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-01 13:28:01-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-01-01 13:28:01-08:00
log99203e4177a7c2fe80b1c08d86c295c61795f33f
tree1f4777ff46633f4f902f7a8f120fbe1b13a637f1
parent4cc374c639a64c087c9c8aaea59d5bb9a6a637e9
parent9c53564af1e00486218a5d345744273ad242ea33
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #7578 from vrischmann/walker

fix segfault in std.fs.Walker

2 files changed, 41 insertions(+), 1 deletions(-)

lib/std/fs.zig+2-1
......@@ -2183,7 +2183,7 @@ pub const Walker = struct {
21832183 while (true) {
21842184 if (self.stack.items.len == 0) return null;
21852185 // `top` becomes invalid after appending to `self.stack`.
2186 const top = &self.stack.items[self.stack.items.len - 1];
2186 var top = &self.stack.items[self.stack.items.len - 1];
21872187 const dirname_len = top.dirname_len;
21882188 if (try top.dir_it.next()) |base| {
21892189 self.name_buffer.shrink(dirname_len);
......@@ -2200,6 +2200,7 @@ pub const Walker = struct {
22002200 .dir_it = new_dir.iterate(),
22012201 .dirname_len = self.name_buffer.items.len,
22022202 });
2203 top = &self.stack.items[self.stack.items.len - 1];
22032204 }
22042205 }
22052206 return Entry{
lib/std/fs/test.zig+39
......@@ -794,3 +794,42 @@ test "open file with exclusive nonblocking lock twice (absolute paths)" {
794794
795795 try fs.deleteFileAbsolute(filename);
796796}
797
798test "walker" {
799 if (builtin.os.tag == .wasi) return error.SkipZigTest;
800
801 var arena = ArenaAllocator.init(testing.allocator);
802 defer arena.deinit();
803 var allocator = &arena.allocator;
804
805 var tmp = tmpDir(.{});
806 defer tmp.cleanup();
807
808 const nb_dirs = 8;
809
810 var i: usize = 0;
811 var sub_dir = tmp.dir;
812 while (i < nb_dirs) : (i += 1) {
813 const dir_name = try std.fmt.allocPrint(allocator, "{}", .{i});
814 try sub_dir.makeDir(dir_name);
815 sub_dir = try sub_dir.openDir(dir_name, .{});
816 }
817
818 const tmp_path = try fs.path.join(allocator, &[_][]const u8{ "zig-cache", "tmp", tmp.sub_path[0..] });
819
820 var walker = try fs.walkPath(testing.allocator, tmp_path);
821 defer walker.deinit();
822
823 i = 0;
824 var expected_dir_name: []const u8 = "";
825 while (i < nb_dirs) : (i += 1) {
826 const name = try std.fmt.allocPrint(allocator, "{}", .{i});
827 expected_dir_name = if (expected_dir_name.len == 0)
828 name
829 else
830 try fs.path.join(allocator, &[_][]const u8{ expected_dir_name, name });
831
832 var entry = (try walker.next()).?;
833 testing.expectEqualStrings(expected_dir_name, try fs.path.relative(allocator, tmp_path, entry.path));
834 }
835}