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 {...@@ -51,11 +51,11 @@ pub const Diagnostics = struct {
51 },51 },
52 };52 };
5353
54 fn findRoot(d: *Diagnostics, path: []const u8) !void {54 fn findRoot(d: *Diagnostics, kind: FileKind, path: []const u8) !void {
55 if (path.len == 0) return;55 if (path.len == 0) return;
5656
57 d.entries += 1;57 d.entries += 1;
58 const root_dir = rootDir(path);58 const root_dir = rootDir(path, kind);
59 if (d.entries == 1) {59 if (d.entries == 1) {
60 d.root_dir = try d.allocator.dupe(u8, root_dir);60 d.root_dir = try d.allocator.dupe(u8, root_dir);
61 return;61 return;
...@@ -67,24 +67,31 @@ pub const Diagnostics = struct {...@@ -67,24 +67,31 @@ pub const Diagnostics = struct {
67 }67 }
6868
69 // Returns root dir of the path, assumes non empty path.69 // 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 {
71 const start_index: usize = if (path[0] == '/') 1 else 0;71 const start_index: usize = if (path[0] == '/') 1 else 0;
72 const end_index: usize = if (path[path.len - 1] == '/') path.len - 1 else path.len;72 const end_index: usize = if (path[path.len - 1] == '/') path.len - 1 else path.len;
73 const buf = path[start_index..end_index];73 const buf = path[start_index..end_index];
74 if (std.mem.indexOfScalarPos(u8, buf, 0, '/')) |idx| {74 if (std.mem.indexOfScalarPos(u8, buf, 0, '/')) |idx| {
75 return buf[0..idx];75 return buf[0..idx];
76 }76 }
77 return buf;77
78 return switch (kind) {
79 .file => "",
80 .sym_link => "",
81 .directory => buf,
82 };
78 }83 }
7984
80 test rootDir {85 test rootDir {
81 const expectEqualStrings = testing.expectEqualStrings;86 const expectEqualStrings = testing.expectEqualStrings;
82 try expectEqualStrings("a", rootDir("a"));87 try expectEqualStrings("", rootDir("a", .file));
83 try expectEqualStrings("b", rootDir("b"));88 try expectEqualStrings("a", rootDir("a", .directory));
84 try expectEqualStrings("c", rootDir("/c"));89 try expectEqualStrings("b", rootDir("b", .directory));
85 try expectEqualStrings("d", rootDir("/d/"));90 try expectEqualStrings("c", rootDir("/c", .directory));
86 try expectEqualStrings("a", rootDir("a/b"));91 try expectEqualStrings("d", rootDir("/d/", .directory));
87 try expectEqualStrings("a", rootDir("a/b/c"));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));
88 }95 }
8996
90 pub fn deinit(d: *Diagnostics) void {97 pub fn deinit(d: *Diagnostics) void {
...@@ -637,7 +644,7 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: PipeOptions)...@@ -637,7 +644,7 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: PipeOptions)
637 continue;644 continue;
638 }645 }
639 if (options.diagnostics) |d| {646 if (options.diagnostics) |d| {
640 try d.findRoot(file_name);647 try d.findRoot(file.kind, file_name);
641 }648 }
642649
643 switch (file.kind) {650 switch (file.kind) {
...@@ -1093,6 +1100,21 @@ test "pipeToFileSystem root_dir" {...@@ -1093,6 +1100,21 @@ test "pipeToFileSystem root_dir" {
1093 }1100 }
1094}1101}
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
1096test "findRoot without explicit root dir" {1118test "findRoot without explicit root dir" {
1097 const data = @embedFile("tar/testdata/19820.tar");1119 const data = @embedFile("tar/testdata/19820.tar");
1098 var fbs = std.io.fixedBufferStream(data);1120 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