mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
Merge pull request #19615 from ianic/tar_diagnostic
std.tar: add strip components error to diagnostics
This commit is contained in:
commit
768b17755e
@ -46,6 +46,9 @@ pub const Diagnostics = struct {
|
||||
file_name: []const u8,
|
||||
file_type: Header.Kind,
|
||||
},
|
||||
components_outside_stripped_prefix: struct {
|
||||
file_name: []const u8,
|
||||
},
|
||||
};
|
||||
|
||||
fn findRoot(d: *Diagnostics, path: []const u8) !void {
|
||||
@ -97,6 +100,9 @@ pub const Diagnostics = struct {
|
||||
.unsupported_file_type => |info| {
|
||||
d.allocator.free(info.file_name);
|
||||
},
|
||||
.components_outside_stripped_prefix => |info| {
|
||||
d.allocator.free(info.file_name);
|
||||
},
|
||||
}
|
||||
}
|
||||
d.errors.deinit(d.allocator);
|
||||
@ -623,18 +629,24 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: PipeOptions)
|
||||
|
||||
while (try iter.next()) |file| {
|
||||
const file_name = stripComponents(file.name, options.strip_components);
|
||||
if (file_name.len == 0 and file.kind != .directory) {
|
||||
const d = options.diagnostics orelse return error.TarComponentsOutsideStrippedPrefix;
|
||||
try d.errors.append(d.allocator, .{ .components_outside_stripped_prefix = .{
|
||||
.file_name = try d.allocator.dupe(u8, file.name),
|
||||
} });
|
||||
continue;
|
||||
}
|
||||
if (options.diagnostics) |d| {
|
||||
try d.findRoot(file_name);
|
||||
}
|
||||
|
||||
switch (file.kind) {
|
||||
.directory => {
|
||||
if (file_name.len != 0 and !options.exclude_empty_directories) {
|
||||
if (file_name.len > 0 and !options.exclude_empty_directories) {
|
||||
try dir.makePath(file_name);
|
||||
}
|
||||
},
|
||||
.file => {
|
||||
if (file_name.len == 0) return error.BadFileName;
|
||||
if (createDirAndFile(dir, file_name, fileMode(file.mode, options))) |fs_file| {
|
||||
defer fs_file.close();
|
||||
try file.writeAll(fs_file);
|
||||
@ -647,7 +659,6 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: PipeOptions)
|
||||
}
|
||||
},
|
||||
.sym_link => {
|
||||
if (file_name.len == 0) return error.BadFileName;
|
||||
const link_name = file.link_name;
|
||||
createDirAndSymlink(dir, link_name, file_name) catch |err| {
|
||||
const d = options.diagnostics orelse return error.UnableToCreateSymLink;
|
||||
@ -1096,6 +1107,30 @@ test "findRoot without explicit root dir" {
|
||||
try testing.expectEqualStrings("root", diagnostics.root_dir);
|
||||
}
|
||||
|
||||
test "pipeToFileSystem strip_components" {
|
||||
const data = @embedFile("tar/testdata/example.tar");
|
||||
var fbs = std.io.fixedBufferStream(data);
|
||||
const reader = fbs.reader();
|
||||
|
||||
var tmp = testing.tmpDir(.{ .no_follow = true });
|
||||
defer tmp.cleanup();
|
||||
var diagnostics: Diagnostics = .{ .allocator = testing.allocator };
|
||||
defer diagnostics.deinit();
|
||||
|
||||
pipeToFileSystem(tmp.dir, reader, .{
|
||||
.strip_components = 3,
|
||||
.diagnostics = &diagnostics,
|
||||
}) catch |err| {
|
||||
// Skip on platform which don't support symlinks
|
||||
if (err == error.UnableToCreateSymLink) return error.SkipZigTest;
|
||||
return err;
|
||||
};
|
||||
|
||||
try testing.expectEqual(2, diagnostics.errors.items.len);
|
||||
try testing.expectEqualStrings("example/b/symlink", diagnostics.errors.items[0].components_outside_stripped_prefix.file_name);
|
||||
try testing.expectEqualStrings("example/a/file", diagnostics.errors.items[1].components_outside_stripped_prefix.file_name);
|
||||
}
|
||||
|
||||
fn normalizePath(bytes: []u8) []u8 {
|
||||
const canonical_sep = std.fs.path.sep_posix;
|
||||
if (std.fs.path.sep == canonical_sep) return bytes;
|
||||
|
||||
@ -1189,6 +1189,7 @@ fn unpackTarball(f: *Fetch, out_dir: fs.Dir, reader: anytype) RunError!UnpackRes
|
||||
.unable_to_create_file => |i| res.unableToCreateFile(stripRoot(i.file_name, res.root_dir), i.code),
|
||||
.unable_to_create_sym_link => |i| res.unableToCreateSymLink(stripRoot(i.file_name, res.root_dir), i.link_name, i.code),
|
||||
.unsupported_file_type => |i| res.unsupportedFileType(stripRoot(i.file_name, res.root_dir), @intFromEnum(i.file_type)),
|
||||
.components_outside_stripped_prefix => unreachable, // unreachable with strip_components = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user