Commit 04e8bbd932
lib/std/tar/test.zig
@@ -315,7 +315,7 @@ test "tar run Go test cases" {
},
.{
.data = @embedFile("testdata/fuzz1.tar"),
- .err = error.TarCorruptInput,
+ .err = error.TarInsufficientBuffer,
},
.{
.data = @embedFile("testdata/fuzz2.tar"),
@@ -328,7 +328,7 @@ test "tar run Go test cases" {
for (cases) |case| {
var fsb = std.io.fixedBufferStream(case.data);
- var iter = tar.iterator(fsb.reader(), .{
+ var iter = try tar.iterator(fsb.reader(), .{
.file_name_buffer = &file_name_buffer,
.link_name_buffer = &link_name_buffer,
});
@@ -359,6 +359,27 @@ test "tar run Go test cases" {
}
try testing.expectEqual(case.files.len, i);
}
+
+ var min_file_name_buffer: [tar.Header.MAX_NAME_SIZE]u8 = undefined;
+ var min_link_name_buffer: [tar.Header.LINK_NAME_SIZE]u8 = undefined;
+ const long_name_cases = [_]Case{ cases[11], cases[25], cases[28] };
+
+ for (long_name_cases) |case| {
+ var fsb = std.io.fixedBufferStream(case.data);
+ var iter = try tar.iterator(fsb.reader(), .{
+ .file_name_buffer = &min_file_name_buffer,
+ .link_name_buffer = &min_link_name_buffer,
+ });
+
+ var iter_err: ?anyerror = null;
+ while (iter.next() catch |err| brk: {
+ iter_err = err;
+ break :brk null;
+ }) |_| {}
+
+ try testing.expect(iter_err != null);
+ try testing.expectEqual(error.TarInsufficientBuffer, iter_err.?);
+ }
}
// used in test to calculate file chksum
@@ -490,6 +511,21 @@ test "tar pipeToFileSystem" {
try testing.expectError(error.FileNotFound, root.dir.statFile("empty"));
try testing.expect((try root.dir.statFile("a/file")).kind == .file);
try testing.expect((try root.dir.statFile("b/symlink")).kind == .file); // statFile follows symlink
+
var buf: [32]u8 = undefined;
try testing.expectEqualSlices(u8, "../a/file", try root.dir.readLink("b/symlink", &buf));
}
+
+test "insufficient buffer for iterator" {
+ var file_name_buffer: [10]u8 = undefined;
+ var link_name_buffer: [10]u8 = undefined;
+
+ var fsb = std.io.fixedBufferStream("");
+ try testing.expectError(
+ error.TarInsufficientBuffer,
+ tar.iterator(fsb.reader(), .{
+ .file_name_buffer = &file_name_buffer,
+ .link_name_buffer = &link_name_buffer,
+ }),
+ );
+}
lib/std/tar.zig
@@ -87,8 +87,8 @@ pub const Options = struct {
pub const Header = struct {
const SIZE = 512;
- const MAX_NAME_SIZE = 100 + 1 + 155; // name(100) + separator(1) + prefix(155)
- const LINK_NAME_SIZE = 100;
+ pub const MAX_NAME_SIZE = 100 + 1 + 155; // name(100) + separator(1) + prefix(155)
+ pub const LINK_NAME_SIZE = 100;
bytes: *const [SIZE]u8,
@@ -248,7 +248,13 @@ pub const IteratorOptions = struct {
/// Iterates over files in tar archive.
/// `next` returns each file in `reader` tar archive.
-pub fn iterator(reader: anytype, options: IteratorOptions) Iterator(@TypeOf(reader)) {
+/// Provided buffers should be at least 256 bytes for file_name and 100 bytes
+/// for link_name.
+pub fn iterator(reader: anytype, options: IteratorOptions) !Iterator(@TypeOf(reader)) {
+ if (options.file_name_buffer.len < Header.MAX_NAME_SIZE or
+ options.link_name_buffer.len < Header.LINK_NAME_SIZE)
+ return error.TarInsufficientBuffer;
+
return .{
.reader = reader,
.diagnostics = options.diagnostics,
@@ -318,7 +324,7 @@ fn Iterator(comptime ReaderType: type) type {
}
fn readString(self: *Self, size: usize, buffer: []u8) ![]const u8 {
- if (size > buffer.len) return error.TarCorruptInput;
+ if (size > buffer.len) return error.TarInsufficientBuffer;
const buf = buffer[0..size];
try self.reader.readNoEof(buf);
return nullStr(buf);
@@ -470,7 +476,8 @@ fn PaxIterator(comptime ReaderType: type) type {
// Copies pax attribute value into destination buffer.
// Must be called with destination buffer of size at least Attribute.len.
pub fn value(self: Attribute, dst: []u8) ![]const u8 {
- assert(self.len <= dst.len);
+ if (self.len > dst.len) return error.TarInsufficientBuffer;
+ // assert(self.len <= dst.len);
const buf = dst[0..self.len];
const n = try self.reader.readAll(buf);
if (n < self.len) return error.UnexpectedEndOfStream;
@@ -558,7 +565,7 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
var file_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
var link_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
- var iter = iterator(reader, .{
+ var iter = try iterator(reader, .{
.file_name_buffer = &file_name_buffer,
.link_name_buffer = &link_name_buffer,
.diagnostics = options.diagnostics,