| ... | @@ -536,14 +536,15 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi | ... | @@ -536,14 +536,15 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi |
| 536 | while (try iter.next()) |file| { | 536 | while (try iter.next()) |file| { |
| 537 | switch (file.kind) { | 537 | switch (file.kind) { |
| 538 | .directory => { | 538 | .directory => { |
| 539 | const file_name = try stripComponents(file.name, options.strip_components); | 539 | const file_name = stripComponents(file.name, options.strip_components); |
| 540 | if (file_name.len != 0 and !options.exclude_empty_directories) { | 540 | if (file_name.len != 0 and !options.exclude_empty_directories) { |
| 541 | try dir.makePath(file_name); | 541 | try dir.makePath(file_name); |
| 542 | } | 542 | } |
| 543 | }, | 543 | }, |
| 544 | .normal => { | 544 | .normal => { |
| 545 | if (file.size == 0 and file.name.len == 0) return; | 545 | 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; |
| 547 | | 548 | |
| 548 | const fs_file = dir.createFile(file_name, .{}) catch |err| switch (err) { | 549 | const fs_file = dir.createFile(file_name, .{}) catch |err| switch (err) { |
| 549 | error.FileNotFound => again: { | 550 | error.FileNotFound => again: { |
| ... | @@ -575,7 +576,8 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi | ... | @@ -575,7 +576,8 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi |
| 575 | }, | 576 | }, |
| 576 | .symbolic_link => { | 577 | .symbolic_link => { |
| 577 | // The file system path of the symbolic link. | 578 | // 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; |
| 579 | // The data inside the symbolic link. | 581 | // The data inside the symbolic link. |
| 580 | const link_name = file.link_name; | 582 | const link_name = file.link_name; |
| 581 | | 583 | |
| ... | @@ -604,14 +606,15 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi | ... | @@ -604,14 +606,15 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi |
| 604 | } | 606 | } |
| 605 | } | 607 | } |
| 606 | | 608 | |
| 607 | fn stripComponents(path: []const u8, count: u32) ![]const u8 { | 609 | fn stripComponents(path: []const u8, count: u32) []const u8 { |
| 608 | var i: usize = 0; | 610 | var i: usize = 0; |
| 609 | var c = count; | 611 | var c = count; |
| 610 | while (c > 0) : (c -= 1) { | 612 | while (c > 0) : (c -= 1) { |
| 611 | if (std.mem.indexOfScalarPos(u8, path, i, '/')) |pos| { | 613 | if (std.mem.indexOfScalarPos(u8, path, i, '/')) |pos| { |
| 612 | i = pos + 1; | 614 | i = pos + 1; |
| 613 | } else { | 615 | } else { |
| 614 | return error.TarComponentsOutsideStrippedPrefix; | 616 | i = path.len; |
| | 617 | break; |
| 615 | } | 618 | } |
| 616 | } | 619 | } |
| 617 | return path[i..]; | 620 | return path[i..]; |
| ... | @@ -619,9 +622,11 @@ fn stripComponents(path: []const u8, count: u32) ![]const u8 { | ... | @@ -619,9 +622,11 @@ fn stripComponents(path: []const u8, count: u32) ![]const u8 { |
| 619 | | 622 | |
| 620 | test "tar stripComponents" { | 623 | test "tar stripComponents" { |
| 621 | const expectEqualStrings = std.testing.expectEqualStrings; | 624 | const expectEqualStrings = std.testing.expectEqualStrings; |
| 622 | try expectEqualStrings("a/b/c", try stripComponents("a/b/c", 0)); | 625 | try expectEqualStrings("a/b/c", stripComponents("a/b/c", 0)); |
| 623 | try expectEqualStrings("b/c", try stripComponents("a/b/c", 1)); | 626 | try expectEqualStrings("b/c", stripComponents("a/b/c", 1)); |
| 624 | try expectEqualStrings("c", try stripComponents("a/b/c", 2)); | 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)); |
| 625 | } | 630 | } |
| 626 | | 631 | |
| 627 | test "tar PaxIterator" { | 632 | test "tar PaxIterator" { |