Commit e20080be13

Igor Anić <igor.anic@gmail.com>
2024-02-14 22:12:54
preserve valuable tests from v1 implementation
Before removal of v1.
1 parent 0afe808
Changed files (2)
lib
std
compress
lib/std/compress/flate/container.zig
@@ -143,9 +143,10 @@ pub const Container = enum {
     }
 
     fn parseZlibHeader(reader: anytype) !void {
-        const cinfo_cm = try reader.read(u8);
+        const cm = try reader.read(u4);
+        const cinfo = try reader.read(u4);
         _ = try reader.read(u8);
-        if (cinfo_cm != 0x78) {
+        if (cm != 8 or cinfo > 7) {
             return error.BadZlibHeader;
         }
     }
lib/std/compress/flate/flate.zig
@@ -234,3 +234,114 @@ test "flate compress/decompress" {
         }
     }
 }
+
+fn testDecompress(comptime container: Container, compressed: []const u8, expected_plain: []const u8) !void {
+    var in_stream = std.io.fixedBufferStream(compressed);
+    var al = std.ArrayList(u8).init(testing.allocator);
+    defer al.deinit();
+
+    try inflate.decompress(container, in_stream.reader(), al.writer());
+
+    try testing.expectEqualSlices(u8, expected_plain, al.items);
+}
+
+test "flate don't read past deflate stream's end" {
+    try testDecompress(.zlib, &[_]u8{
+        0x08, 0xd7, 0x63, 0xf8, 0xcf, 0xc0, 0xc0, 0x00, 0xc1, 0xff,
+        0xff, 0x43, 0x30, 0x03, 0x03, 0xc3, 0xff, 0xff, 0xff, 0x01,
+        0x83, 0x95, 0x0b, 0xf5,
+    }, &[_]u8{
+        0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
+        0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
+        0x00, 0x00, 0xff, 0xff, 0xff,
+    });
+}
+
+test "flate zlib header" {
+    // Truncated header
+    try testing.expectError(
+        error.EndOfStream,
+        testDecompress(.zlib, &[_]u8{0x78}, ""),
+    );
+    // Wrong CM
+    try testing.expectError(
+        error.BadZlibHeader,
+        testDecompress(.zlib, &[_]u8{ 0x79, 0x94 }, ""),
+    );
+    // Wrong CINFO
+    try testing.expectError(
+        error.BadZlibHeader,
+        testDecompress(.zlib, &[_]u8{ 0x88, 0x98 }, ""),
+    );
+    // Wrong checksum
+    try testing.expectError(
+        error.WrongZlibChecksum,
+        testDecompress(.zlib, &[_]u8{ 0x78, 0xda, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, ""),
+    );
+    // Truncated checksum
+    try testing.expectError(
+        error.EndOfStream,
+        testDecompress(.zlib, &[_]u8{ 0x78, 0xda, 0x03, 0x00, 0x00 }, ""),
+    );
+}
+
+test "flate gzip header" {
+    // Truncated header
+    try testing.expectError(
+        error.EndOfStream,
+        testDecompress(.gzip, &[_]u8{ 0x1f, 0x8B }, undefined),
+    );
+    // Wrong CM
+    try testing.expectError(
+        error.BadGzipHeader,
+        testDecompress(.gzip, &[_]u8{
+            0x1f, 0x8b, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x03,
+        }, undefined),
+    );
+
+    // Wrong checksum
+    try testing.expectError(
+        error.WrongGzipChecksum,
+        testDecompress(.gzip, &[_]u8{
+            0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01,
+            0x00, 0x00, 0x00, 0x00,
+        }, undefined),
+    );
+    // Truncated checksum
+    try testing.expectError(
+        error.EndOfStream,
+        testDecompress(.gzip, &[_]u8{
+            0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
+        }, undefined),
+    );
+    // Wrong initial size
+    try testing.expectError(
+        error.WrongGzipSize,
+        testDecompress(.gzip, &[_]u8{
+            0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x01,
+        }, undefined),
+    );
+    // Truncated initial size field
+    try testing.expectError(
+        error.EndOfStream,
+        testDecompress(.gzip, &[_]u8{
+            0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00,
+        }, undefined),
+    );
+
+    try testDecompress(.gzip, &[_]u8{
+        // GZIP header
+        0x1f, 0x8b, 0x08, 0x12, 0x00, 0x09, 0x6e, 0x88, 0x00, 0xff, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x00,
+        // header.FHCRC (should cover entire header)
+        0x99, 0xd6,
+        // GZIP data
+        0x01, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    }, "");
+}