Skip to content

Commit 5be3c78

Browse files
authored
std.tar: pass entry kind to rootDir to avoid setting root_dir to file (#23456)
1 parent 1a2ceb3 commit 5be3c78

File tree

2 files changed

+33
-11
lines changed

2 files changed

+33
-11
lines changed

lib/std/tar.zig

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

1103+
test "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+
10961118
test "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

10 KB
Binary file not shown.

0 commit comments

Comments
 (0)