authorgravatar for cipharius@pm.mecipharius <cipharius@pm.me> 2023-11-30 17:51:29+02:00
committergravatar for cipharius@pm.mecipharius <cipharius@pm.me> 2024-01-15 18:31:32+02:00
logf25c499d121ab21f1de985da3f36df3cc0118362
treee407598f3a5a2aa32b4d54a5c7912efbd82290ca
parent2e7795662973cc0a2deda7e918495a1020a4c7d5

Permits tar directory path without trailing slash


1 files changed, 13 insertions(+), 8 deletions(-)

lib/std/tar.zig+13-8
......@@ -536,14 +536,15 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
536536 while (try iter.next()) |file| {
537537 switch (file.kind) {
538538 .directory => {
539 const file_name = try stripComponents(file.name, options.strip_components);
539 const file_name = stripComponents(file.name, options.strip_components);
540540 if (file_name.len != 0 and !options.exclude_empty_directories) {
541541 try dir.makePath(file_name);
542542 }
543543 },
544544 .normal => {
545545 if (file.size == 0 and file.name.len == 0) return;
546 const file_name = try stripComponents(file.name, options.strip_components);
546 const file_name = stripComponents(file.name, options.strip_components);
547 if (file_name.len == 0) return error.BadFileName;
547548
548549 const fs_file = dir.createFile(file_name, .{}) catch |err| switch (err) {
549550 error.FileNotFound => again: {
......@@ -575,7 +576,8 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
575576 },
576577 .symbolic_link => {
577578 // The file system path of the symbolic link.
578 const file_name = try stripComponents(file.name, options.strip_components);
579 const file_name = stripComponents(file.name, options.strip_components);
580 if (file_name.len == 0) return error.BadFileName;
579581 // The data inside the symbolic link.
580582 const link_name = file.link_name;
581583
......@@ -604,14 +606,15 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
604606 }
605607}
606608
607fn stripComponents(path: []const u8, count: u32) ![]const u8 {
609fn stripComponents(path: []const u8, count: u32) []const u8 {
608610 var i: usize = 0;
609611 var c = count;
610612 while (c > 0) : (c -= 1) {
611613 if (std.mem.indexOfScalarPos(u8, path, i, '/')) |pos| {
612614 i = pos + 1;
613615 } else {
614 return error.TarComponentsOutsideStrippedPrefix;
616 i = path.len;
617 break;
615618 }
616619 }
617620 return path[i..];
......@@ -619,9 +622,11 @@ fn stripComponents(path: []const u8, count: u32) ![]const u8 {
619622
620623test "tar stripComponents" {
621624 const expectEqualStrings = std.testing.expectEqualStrings;
622 try expectEqualStrings("a/b/c", try stripComponents("a/b/c", 0));
623 try expectEqualStrings("b/c", try stripComponents("a/b/c", 1));
624 try expectEqualStrings("c", try stripComponents("a/b/c", 2));
625 try expectEqualStrings("a/b/c", stripComponents("a/b/c", 0));
626 try expectEqualStrings("b/c", stripComponents("a/b/c", 1));
627 try expectEqualStrings("c", stripComponents("a/b/c", 2));
628 try expectEqualStrings("", stripComponents("a/b/c", 3));
629 try expectEqualStrings("", stripComponents("a/b/c", 4));
625630}
626631
627632test "tar PaxIterator" {