Skip to content

Commit 64c8197

Browse files
committed
Permits tar directory path without trailing slash
1 parent 42a7247 commit 64c8197

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

lib/std/tar.zig

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -209,14 +209,15 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
209209
file_name_override_len = 0;
210210
switch (header.fileType()) {
211211
.directory => {
212-
const file_name = try stripComponents(unstripped_file_name, options.strip_components);
212+
const file_name = stripComponents(unstripped_file_name, options.strip_components);
213213
if (file_name.len != 0 and !options.exclude_empty_directories) {
214214
try dir.makePath(file_name);
215215
}
216216
},
217217
.normal => {
218218
if (file_size == 0 and unstripped_file_name.len == 0) return;
219-
const file_name = try stripComponents(unstripped_file_name, options.strip_components);
219+
const file_name = stripComponents(unstripped_file_name, options.strip_components);
220+
if (file_name.len == 0) return error.BadFileName;
220221

221222
const file = dir.createFile(file_name, .{}) catch |err| switch (err) {
222223
error.FileNotFound => again: {
@@ -299,7 +300,8 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
299300
.hard_link => return error.TarUnsupportedFileType,
300301
.symbolic_link => {
301302
// The file system path of the symbolic link.
302-
const file_name = try stripComponents(unstripped_file_name, options.strip_components);
303+
const file_name = stripComponents(unstripped_file_name, options.strip_components);
304+
if (file_name.len == 0) return error.BadFileName;
303305
// The data inside the symbolic link.
304306
const link_name = header.linkName();
305307

@@ -334,24 +336,27 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
334336
}
335337
}
336338

337-
fn stripComponents(path: []const u8, count: u32) ![]const u8 {
339+
fn stripComponents(path: []const u8, count: u32) []const u8 {
338340
var i: usize = 0;
339341
var c = count;
340342
while (c > 0) : (c -= 1) {
341343
if (std.mem.indexOfScalarPos(u8, path, i, '/')) |pos| {
342344
i = pos + 1;
343345
} else {
344-
return error.TarComponentsOutsideStrippedPrefix;
346+
i = path.len;
347+
break;
345348
}
346349
}
347350
return path[i..];
348351
}
349352

350353
test stripComponents {
351354
const expectEqualStrings = std.testing.expectEqualStrings;
352-
try expectEqualStrings("a/b/c", try stripComponents("a/b/c", 0));
353-
try expectEqualStrings("b/c", try stripComponents("a/b/c", 1));
354-
try expectEqualStrings("c", try stripComponents("a/b/c", 2));
355+
try expectEqualStrings("a/b/c", stripComponents("a/b/c", 0));
356+
try expectEqualStrings("b/c", stripComponents("a/b/c", 1));
357+
try expectEqualStrings("c", stripComponents("a/b/c", 2));
358+
try expectEqualStrings("", stripComponents("a/b/c", 3));
359+
try expectEqualStrings("", stripComponents("a/b/c", 4));
355360
}
356361

357362
const PaxAttributeInfo = struct {

0 commit comments

Comments
 (0)