authorgravatar for tobias.simetsreiter@wabtec.comTobias Simetsreiter <tobias.simetsreiter@wabtec.com> 2025-04-16 21:17:25+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-04-16 19:17:25+00:00
log5be3c7874ce479df262f243f46079ede9a5f0789
tree3c93bbf8bd738a01b290dc4dc82210dbd0aebf4f
parent1a2ceb36c82cae63d30d99ecfadb22bdf2a977fe
signaturebadge-check Signed by PGP key B5690EEEBB952194

std.tar: pass entry kind to rootDir to avoid setting root_dir to file (#23456)


2 files changed, 33 insertions(+), 11 deletions(-)

lib/std/tar.zig+33-11
......@@ -51,11 +51,11 @@ pub const Diagnostics = struct {
5151 },
5252 };
5353
54 fn findRoot(d: *Diagnostics, path: []const u8) !void {
54 fn findRoot(d: *Diagnostics, kind: FileKind, path: []const u8) !void {
5555 if (path.len == 0) return;
5656
5757 d.entries += 1;
58 const root_dir = rootDir(path);
58 const root_dir = rootDir(path, kind);
5959 if (d.entries == 1) {
6060 d.root_dir = try d.allocator.dupe(u8, root_dir);
6161 return;
......@@ -67,24 +67,31 @@ pub const Diagnostics = struct {
6767 }
6868
6969 // Returns root dir of the path, assumes non empty path.
70 fn rootDir(path: []const u8) []const u8 {
70 fn rootDir(path: []const u8, kind: FileKind) []const u8 {
7171 const start_index: usize = if (path[0] == '/') 1 else 0;
7272 const end_index: usize = if (path[path.len - 1] == '/') path.len - 1 else path.len;
7373 const buf = path[start_index..end_index];
7474 if (std.mem.indexOfScalarPos(u8, buf, 0, '/')) |idx| {
7575 return buf[0..idx];
7676 }
77 return buf;
77
78 return switch (kind) {
79 .file => "",
80 .sym_link => "",
81 .directory => buf,
82 };
7883 }
7984
8085 test rootDir {
8186 const expectEqualStrings = testing.expectEqualStrings;
82 try expectEqualStrings("a", rootDir("a"));
83 try expectEqualStrings("b", rootDir("b"));
84 try expectEqualStrings("c", rootDir("/c"));
85 try expectEqualStrings("d", rootDir("/d/"));
86 try expectEqualStrings("a", rootDir("a/b"));
87 try expectEqualStrings("a", rootDir("a/b/c"));
87 try expectEqualStrings("", rootDir("a", .file));
88 try expectEqualStrings("a", rootDir("a", .directory));
89 try expectEqualStrings("b", rootDir("b", .directory));
90 try expectEqualStrings("c", rootDir("/c", .directory));
91 try expectEqualStrings("d", rootDir("/d/", .directory));
92 try expectEqualStrings("a", rootDir("a/b", .directory));
93 try expectEqualStrings("a", rootDir("a/b", .file));
94 try expectEqualStrings("a", rootDir("a/b/c", .directory));
8895 }
8996
9097 pub fn deinit(d: *Diagnostics) void {
......@@ -637,7 +644,7 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: PipeOptions)
637644 continue;
638645 }
639646 if (options.diagnostics) |d| {
640 try d.findRoot(file_name);
647 try d.findRoot(file.kind, file_name);
641648 }
642649
643650 switch (file.kind) {
......@@ -1093,6 +1100,21 @@ test "pipeToFileSystem root_dir" {
10931100 }
10941101}
10951102
1103test "findRoot with single file archive" {
1104 const data = @embedFile("tar/testdata/22752.tar");
1105 var fbs = std.io.fixedBufferStream(data);
1106 const reader = fbs.reader();
1107
1108 var tmp = testing.tmpDir(.{});
1109 defer tmp.cleanup();
1110
1111 var diagnostics: Diagnostics = .{ .allocator = testing.allocator };
1112 defer diagnostics.deinit();
1113 try pipeToFileSystem(tmp.dir, reader, .{ .diagnostics = &diagnostics });
1114
1115 try testing.expectEqualStrings("", diagnostics.root_dir);
1116}
1117
10961118test "findRoot without explicit root dir" {
10971119 const data = @embedFile("tar/testdata/19820.tar");
10981120 var fbs = std.io.fixedBufferStream(data);
lib/std/tar/testdata/22752.tar created
Binary files /dev/null and b/lib/std/tar/testdata/22752.tar differ