master
  1const std = @import("../../std.zig");
  2const testing = std.testing;
  3const xz = std.compress.xz;
  4
  5fn decompress(data: []const u8) ![]u8 {
  6    const gpa = testing.allocator;
  7
  8    var in_stream: std.Io.Reader = .fixed(data);
  9
 10    var xz_stream = try xz.Decompress.init(&in_stream, gpa, &.{});
 11    defer xz_stream.deinit();
 12
 13    return xz_stream.reader.allocRemaining(gpa, .unlimited);
 14}
 15
 16fn testReader(data: []const u8, expected: []const u8) !void {
 17    const gpa = testing.allocator;
 18
 19    const result = try decompress(data);
 20    defer gpa.free(result);
 21
 22    try testing.expectEqualSlices(u8, expected, result);
 23}
 24
 25fn testDecompressError(expected: anyerror, compressed: []const u8) !void {
 26    const gpa = std.testing.allocator;
 27    var stream: std.Io.Reader = .fixed(compressed);
 28
 29    var decompressor = try xz.Decompress.init(&stream, gpa, &.{});
 30    defer decompressor.deinit();
 31
 32    try std.testing.expectError(error.ReadFailed, decompressor.reader.allocRemaining(gpa, .unlimited));
 33    try std.testing.expectEqual(expected, decompressor.err orelse return error.TestFailed);
 34}
 35
 36test "fixture good-0-empty.xz" {
 37    try testReader(@embedFile("testdata/good-0-empty.xz"), "");
 38}
 39
 40const hello_world_text =
 41    \\Hello
 42    \\World!
 43    \\
 44;
 45
 46test "fixture good-1-check-none.xz" {
 47    try testReader(@embedFile("testdata/good-1-check-none.xz"), hello_world_text);
 48}
 49
 50test "fixture good-1-check-crc32.xz" {
 51    try testReader(@embedFile("testdata/good-1-check-crc32.xz"), hello_world_text);
 52}
 53
 54test "fixture good-1-check-crc64.xz" {
 55    try testReader(@embedFile("testdata/good-1-check-crc64.xz"), hello_world_text);
 56}
 57
 58test "fixture good-1-check-sha256.xz" {
 59    try testReader(@embedFile("testdata/good-1-check-sha256.xz"), hello_world_text);
 60}
 61
 62test "fixture good-2-lzma2.xz" {
 63    try testReader(@embedFile("testdata/good-2-lzma2.xz"), hello_world_text);
 64}
 65
 66test "fixture good-1-block_header-1.xz" {
 67    try testReader(@embedFile("testdata/good-1-block_header-1.xz"), hello_world_text);
 68}
 69
 70test "fixture good-1-block_header-2.xz" {
 71    try testReader(@embedFile("testdata/good-1-block_header-2.xz"), hello_world_text);
 72}
 73
 74test "fixture good-1-block_header-3.xz" {
 75    try testReader(@embedFile("testdata/good-1-block_header-3.xz"), hello_world_text);
 76}
 77
 78const lorem_ipsum_text =
 79    \\Lorem ipsum dolor sit amet, consectetur adipisicing 
 80    \\elit, sed do eiusmod tempor incididunt ut 
 81    \\labore et dolore magna aliqua. Ut enim 
 82    \\ad minim veniam, quis nostrud exercitation ullamco 
 83    \\laboris nisi ut aliquip ex ea commodo 
 84    \\consequat. Duis aute irure dolor in reprehenderit 
 85    \\in voluptate velit esse cillum dolore eu 
 86    \\fugiat nulla pariatur. Excepteur sint occaecat cupidatat 
 87    \\non proident, sunt in culpa qui officia 
 88    \\deserunt mollit anim id est laborum. 
 89    \\
 90;
 91
 92test "fixture good-1-lzma2-1.xz" {
 93    try testReader(@embedFile("testdata/good-1-lzma2-1.xz"), lorem_ipsum_text);
 94}
 95
 96test "fixture good-1-lzma2-2.xz" {
 97    try testReader(@embedFile("testdata/good-1-lzma2-2.xz"), lorem_ipsum_text);
 98}
 99
100test "fixture good-1-lzma2-3.xz" {
101    try testReader(@embedFile("testdata/good-1-lzma2-3.xz"), lorem_ipsum_text);
102}
103
104test "fixture good-1-lzma2-4.xz" {
105    try testReader(@embedFile("testdata/good-1-lzma2-4.xz"), lorem_ipsum_text);
106}
107
108test "fixture good-1-lzma2-5.xz" {
109    try testReader(@embedFile("testdata/good-1-lzma2-5.xz"), "");
110}
111
112test "fixture good-1-delta-lzma2.tiff.xz" {
113    try testDecompressError(error.Unsupported, @embedFile("testdata/good-1-delta-lzma2.tiff.xz"));
114}
115
116test "fixture good-1-x86-lzma2.xz" {
117    try testDecompressError(error.Unsupported, @embedFile("testdata/good-1-x86-lzma2.xz"));
118}
119
120test "fixture good-1-sparc-lzma2.xz" {
121    try testDecompressError(error.Unsupported, @embedFile("testdata/good-1-sparc-lzma2.xz"));
122}
123
124test "fixture good-1-arm64-lzma2-1.xz" {
125    try testDecompressError(error.Unsupported, @embedFile("testdata/good-1-arm64-lzma2-1.xz"));
126}
127
128test "fixture good-1-arm64-lzma2-2.xz" {
129    try testDecompressError(error.Unsupported, @embedFile("testdata/good-1-arm64-lzma2-2.xz"));
130}
131
132test "fixture good-1-3delta-lzma2.xz" {
133    try testDecompressError(error.Unsupported, @embedFile("testdata/good-1-3delta-lzma2.xz"));
134}
135
136test "fixture good-1-empty-bcj-lzma2.xz" {
137    try testDecompressError(error.Unsupported, @embedFile("testdata/good-1-empty-bcj-lzma2.xz"));
138}
139
140fn testDontPanic(data: []const u8) !void {
141    const buf = decompress(data) catch |err| switch (err) {
142        error.OutOfMemory => |e| return e,
143        else => return,
144    };
145    defer testing.allocator.free(buf);
146}
147
148test "size fields: integer overflow avoidance" {
149    // These cases were found via fuzz testing and each previously caused
150    // an integer overflow when decoding. We just want to ensure they no longer
151    // cause a panic
152    // TODO this not a sufficient way to test. tests should always check the result,
153    // not merely ensure that the code does not crash.
154    const header_size_overflow = "\xfd7zXZ\x00\x00\x01i\"\xde6z";
155    try testDontPanic(header_size_overflow);
156    const lzma2_chunk_size_overflow = "\xfd7zXZ\x00\x00\x01i\"\xde6\x02\x00!\x01\x08\x00\x00\x00\xd8\x0f#\x13\x01\xff\xff";
157    try testDontPanic(lzma2_chunk_size_overflow);
158    const backward_size_overflow = "\xfd7zXZ\x00\x00\x01i\"\xde6\x00\x00\x00\x00\x1c\xdfD!\x90B\x99\r\x01\x00\x00\xff\xff\x10\x00\x00\x00\x01DD\xff\xff\xff\x01";
159    try testDontPanic(backward_size_overflow);
160}