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}