| ... | @@ -44,14 +44,13 @@ const State = union(enum) { | ... | @@ -44,14 +44,13 @@ const State = union(enum) { |
| 44 | pub const Error = Container.Error || error{ | 44 | pub const Error = Container.Error || error{ |
| 45 | InvalidCode, | 45 | InvalidCode, |
| 46 | InvalidMatch, | 46 | InvalidMatch, |
| 47 | InvalidBlockType, | | |
| 48 | WrongStoredBlockNlen, | 47 | WrongStoredBlockNlen, |
| 49 | InvalidDynamicBlockHeader, | 48 | InvalidDynamicBlockHeader, |
| 50 | EndOfStream, | | |
| 51 | ReadFailed, | 49 | ReadFailed, |
| 52 | OversubscribedHuffmanTree, | 50 | OversubscribedHuffmanTree, |
| 53 | IncompleteHuffmanTree, | 51 | IncompleteHuffmanTree, |
| 54 | MissingEndOfBlockCode, | 52 | MissingEndOfBlockCode, |
| | 53 | EndOfStream, |
| 55 | }; | 54 | }; |
| 56 | | 55 | |
| 57 | pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress { | 56 | pub fn init(input: *Reader, container: Container, buffer: []u8) Decompress { |
| ... | @@ -153,7 +152,14 @@ fn decodeSymbol(self: *Decompress, decoder: anytype) !Symbol { | ... | @@ -153,7 +152,14 @@ fn decodeSymbol(self: *Decompress, decoder: anytype) !Symbol { |
| 153 | pub fn stream(r: *Reader, w: *Writer, limit: std.Io.Limit) Reader.StreamError!usize { | 152 | pub fn stream(r: *Reader, w: *Writer, limit: std.Io.Limit) Reader.StreamError!usize { |
| 154 | const d: *Decompress = @alignCast(@fieldParentPtr("reader", r)); | 153 | const d: *Decompress = @alignCast(@fieldParentPtr("reader", r)); |
| 155 | return readInner(d, w, limit) catch |err| switch (err) { | 154 | return readInner(d, w, limit) catch |err| switch (err) { |
| 156 | error.EndOfStream => return error.EndOfStream, | 155 | error.EndOfStream => { |
| | 156 | if (d.state == .end) { |
| | 157 | return error.EndOfStream; |
| | 158 | } else { |
| | 159 | d.read_err = error.EndOfStream; |
| | 160 | return error.ReadFailed; |
| | 161 | } |
| | 162 | }, |
| 157 | error.WriteFailed => return error.WriteFailed, | 163 | error.WriteFailed => return error.WriteFailed, |
| 158 | else => |e| { | 164 | else => |e| { |
| 159 | // In the event of an error, state is unmodified so that it can be | 165 | // In the event of an error, state is unmodified so that it can be |
| ... | @@ -922,120 +928,109 @@ test "zlib decompress non compressed block (type 0)" { | ... | @@ -922,120 +928,109 @@ test "zlib decompress non compressed block (type 0)" { |
| 922 | } | 928 | } |
| 923 | | 929 | |
| 924 | test "failing end-of-stream" { | 930 | test "failing end-of-stream" { |
| 925 | try testFailure(@embedFile("testdata/fuzz/end-of-stream.input"), error.EndOfStream); | 931 | try testFailure(.raw, @embedFile("testdata/fuzz/end-of-stream.input"), error.EndOfStream); |
| 926 | } | 932 | } |
| 927 | test "failing invalid-distance" { | 933 | test "failing invalid-distance" { |
| 928 | try testFailure(@embedFile("testdata/fuzz/invalid-distance.input"), error.InvalidMatch); | 934 | try testFailure(.raw, @embedFile("testdata/fuzz/invalid-distance.input"), error.InvalidMatch); |
| 929 | } | 935 | } |
| 930 | test "failing invalid-tree01" { | 936 | test "failing invalid-tree01" { |
| 931 | try testFailure(@embedFile("testdata/fuzz/invalid-tree01.input"), error.IncompleteHuffmanTree); | 937 | try testFailure(.raw, @embedFile("testdata/fuzz/invalid-tree01.input"), error.IncompleteHuffmanTree); |
| 932 | } | 938 | } |
| 933 | test "failing invalid-tree02" { | 939 | test "failing invalid-tree02" { |
| 934 | try testFailure(@embedFile("testdata/fuzz/invalid-tree02.input"), error.IncompleteHuffmanTree); | 940 | try testFailure(.raw, @embedFile("testdata/fuzz/invalid-tree02.input"), error.IncompleteHuffmanTree); |
| 935 | } | 941 | } |
| 936 | test "failing invalid-tree03" { | 942 | test "failing invalid-tree03" { |
| 937 | try testFailure(@embedFile("testdata/fuzz/invalid-tree03.input"), error.IncompleteHuffmanTree); | 943 | try testFailure(.raw, @embedFile("testdata/fuzz/invalid-tree03.input"), error.IncompleteHuffmanTree); |
| 938 | } | 944 | } |
| 939 | test "failing lengths-overflow" { | 945 | test "failing lengths-overflow" { |
| 940 | try testFailure(@embedFile("testdata/fuzz/lengths-overflow.input"), error.InvalidDynamicBlockHeader); | 946 | try testFailure(.raw, @embedFile("testdata/fuzz/lengths-overflow.input"), error.InvalidDynamicBlockHeader); |
| 941 | } | 947 | } |
| 942 | test "failing out-of-codes" { | 948 | test "failing out-of-codes" { |
| 943 | try testFailure(@embedFile("testdata/fuzz/out-of-codes.input"), error.InvalidCode); | 949 | try testFailure(.raw, @embedFile("testdata/fuzz/out-of-codes.input"), error.InvalidCode); |
| 944 | } | 950 | } |
| 945 | test "failing puff01" { | 951 | test "failing puff01" { |
| 946 | try testFailure(@embedFile("testdata/fuzz/puff01.input"), error.WrongStoredBlockNlen); | 952 | try testFailure(.raw, @embedFile("testdata/fuzz/puff01.input"), error.WrongStoredBlockNlen); |
| 947 | } | 953 | } |
| 948 | test "failing puff02" { | 954 | test "failing puff02" { |
| 949 | try testFailure(@embedFile("testdata/fuzz/puff02.input"), error.EndOfStream); | 955 | try testFailure(.raw, @embedFile("testdata/fuzz/puff02.input"), error.EndOfStream); |
| 950 | } | 956 | } |
| 951 | test "failing puff04" { | 957 | test "failing puff04" { |
| 952 | try testFailure(@embedFile("testdata/fuzz/puff04.input"), error.InvalidCode); | 958 | try testFailure(.raw, @embedFile("testdata/fuzz/puff04.input"), error.InvalidCode); |
| 953 | } | 959 | } |
| 954 | test "failing puff05" { | 960 | test "failing puff05" { |
| 955 | try testFailure(@embedFile("testdata/fuzz/puff05.input"), error.EndOfStream); | 961 | try testFailure(.raw, @embedFile("testdata/fuzz/puff05.input"), error.EndOfStream); |
| 956 | } | 962 | } |
| 957 | test "failing puff06" { | 963 | test "failing puff06" { |
| 958 | try testFailure(@embedFile("testdata/fuzz/puff06.input"), error.EndOfStream); | 964 | try testFailure(.raw, @embedFile("testdata/fuzz/puff06.input"), error.EndOfStream); |
| 959 | } | 965 | } |
| 960 | test "failing puff08" { | 966 | test "failing puff08" { |
| 961 | try testFailure(@embedFile("testdata/fuzz/puff08.input"), error.InvalidCode); | 967 | try testFailure(.raw, @embedFile("testdata/fuzz/puff08.input"), error.InvalidCode); |
| 962 | } | 968 | } |
| 963 | test "failing puff10" { | 969 | test "failing puff10" { |
| 964 | try testFailure(@embedFile("testdata/fuzz/puff10.input"), error.InvalidCode); | 970 | try testFailure(.raw, @embedFile("testdata/fuzz/puff10.input"), error.InvalidCode); |
| 965 | } | 971 | } |
| 966 | test "failing puff11" { | 972 | test "failing puff11" { |
| 967 | try testFailure(@embedFile("testdata/fuzz/puff11.input"), error.InvalidMatch); | 973 | try testFailure(.raw, @embedFile("testdata/fuzz/puff11.input"), error.InvalidMatch); |
| 968 | } | 974 | } |
| 969 | test "failing puff12" { | 975 | test "failing puff12" { |
| 970 | try testFailure(@embedFile("testdata/fuzz/puff12.input"), error.InvalidDynamicBlockHeader); | 976 | try testFailure(.raw, @embedFile("testdata/fuzz/puff12.input"), error.InvalidDynamicBlockHeader); |
| 971 | } | 977 | } |
| 972 | test "failing puff13" { | 978 | test "failing puff13" { |
| 973 | try testFailure(@embedFile("testdata/fuzz/puff13.input"), error.IncompleteHuffmanTree); | 979 | try testFailure(.raw, @embedFile("testdata/fuzz/puff13.input"), error.IncompleteHuffmanTree); |
| 974 | } | 980 | } |
| 975 | test "failing puff14" { | 981 | test "failing puff14" { |
| 976 | try testFailure(@embedFile("testdata/fuzz/puff14.input"), error.EndOfStream); | 982 | try testFailure(.raw, @embedFile("testdata/fuzz/puff14.input"), error.EndOfStream); |
| 977 | } | 983 | } |
| 978 | test "failing puff15" { | 984 | test "failing puff15" { |
| 979 | try testFailure(@embedFile("testdata/fuzz/puff15.input"), error.IncompleteHuffmanTree); | 985 | try testFailure(.raw, @embedFile("testdata/fuzz/puff15.input"), error.IncompleteHuffmanTree); |
| 980 | } | 986 | } |
| 981 | test "failing puff16" { | 987 | test "failing puff16" { |
| 982 | try testFailure(@embedFile("testdata/fuzz/puff16.input"), error.InvalidDynamicBlockHeader); | 988 | try testFailure(.raw, @embedFile("testdata/fuzz/puff16.input"), error.InvalidDynamicBlockHeader); |
| 983 | } | 989 | } |
| 984 | test "failing puff17" { | 990 | test "failing puff17" { |
| 985 | try testFailure(@embedFile("testdata/fuzz/puff17.input"), error.MissingEndOfBlockCode); | 991 | try testFailure(.raw, @embedFile("testdata/fuzz/puff17.input"), error.MissingEndOfBlockCode); |
| 986 | } | 992 | } |
| 987 | test "failing fuzz1" { | 993 | test "failing fuzz1" { |
| 988 | try testFailure(@embedFile("testdata/fuzz/fuzz1.input"), error.InvalidDynamicBlockHeader); | 994 | try testFailure(.raw, @embedFile("testdata/fuzz/fuzz1.input"), error.InvalidDynamicBlockHeader); |
| 989 | } | 995 | } |
| 990 | test "failing fuzz2" { | 996 | test "failing fuzz2" { |
| 991 | try testFailure(@embedFile("testdata/fuzz/fuzz2.input"), error.InvalidDynamicBlockHeader); | 997 | try testFailure(.raw, @embedFile("testdata/fuzz/fuzz2.input"), error.InvalidDynamicBlockHeader); |
| 992 | } | 998 | } |
| 993 | test "failing fuzz3" { | 999 | test "failing fuzz3" { |
| 994 | try testFailure(@embedFile("testdata/fuzz/fuzz3.input"), error.InvalidMatch); | 1000 | try testFailure(.raw, @embedFile("testdata/fuzz/fuzz3.input"), error.InvalidMatch); |
| 995 | } | 1001 | } |
| 996 | test "failing fuzz4" { | 1002 | test "failing fuzz4" { |
| 997 | try testFailure(@embedFile("testdata/fuzz/fuzz4.input"), error.OversubscribedHuffmanTree); | 1003 | try testFailure(.raw, @embedFile("testdata/fuzz/fuzz4.input"), error.OversubscribedHuffmanTree); |
| 998 | } | 1004 | } |
| 999 | test "failing puff18" { | 1005 | test "failing puff18" { |
| 1000 | try testFailure(@embedFile("testdata/fuzz/puff18.input"), error.OversubscribedHuffmanTree); | 1006 | try testFailure(.raw, @embedFile("testdata/fuzz/puff18.input"), error.OversubscribedHuffmanTree); |
| 1001 | } | 1007 | } |
| 1002 | test "failing puff19" { | 1008 | test "failing puff19" { |
| 1003 | try testFailure(@embedFile("testdata/fuzz/puff19.input"), error.OversubscribedHuffmanTree); | 1009 | try testFailure(.raw, @embedFile("testdata/fuzz/puff19.input"), error.OversubscribedHuffmanTree); |
| 1004 | } | 1010 | } |
| 1005 | test "failing puff20" { | 1011 | test "failing puff20" { |
| 1006 | try testFailure(@embedFile("testdata/fuzz/puff20.input"), error.OversubscribedHuffmanTree); | 1012 | try testFailure(.raw, @embedFile("testdata/fuzz/puff20.input"), error.OversubscribedHuffmanTree); |
| 1007 | } | 1013 | } |
| 1008 | test "failing puff21" { | 1014 | test "failing puff21" { |
| 1009 | try testFailure(@embedFile("testdata/fuzz/puff21.input"), error.OversubscribedHuffmanTree); | 1015 | try testFailure(.raw, @embedFile("testdata/fuzz/puff21.input"), error.OversubscribedHuffmanTree); |
| 1010 | } | 1016 | } |
| 1011 | test "failing puff22" { | 1017 | test "failing puff22" { |
| 1012 | try testFailure(@embedFile("testdata/fuzz/puff22.input"), error.OversubscribedHuffmanTree); | 1018 | try testFailure(.raw, @embedFile("testdata/fuzz/puff22.input"), error.OversubscribedHuffmanTree); |
| 1013 | } | 1019 | } |
| 1014 | test "failing puff23" { | 1020 | test "failing puff23" { |
| 1015 | try testFailure(@embedFile("testdata/fuzz/puff23.input"), error.OversubscribedHuffmanTree); | 1021 | try testFailure(.raw, @embedFile("testdata/fuzz/puff23.input"), error.OversubscribedHuffmanTree); |
| 1016 | } | 1022 | } |
| 1017 | test "failing puff24" { | 1023 | test "failing puff24" { |
| 1018 | try testFailure(@embedFile("testdata/fuzz/puff24.input"), error.IncompleteHuffmanTree); | 1024 | try testFailure(.raw, @embedFile("testdata/fuzz/puff24.input"), error.IncompleteHuffmanTree); |
| 1019 | } | 1025 | } |
| 1020 | test "failing puff25" { | 1026 | test "failing puff25" { |
| 1021 | try testFailure(@embedFile("testdata/fuzz/puff25.input"), error.OversubscribedHuffmanTree); | 1027 | try testFailure(.raw, @embedFile("testdata/fuzz/puff25.input"), error.OversubscribedHuffmanTree); |
| 1022 | } | 1028 | } |
| 1023 | test "failing puff26" { | 1029 | test "failing puff26" { |
| 1024 | try testFailure(@embedFile("testdata/fuzz/puff26.input"), error.InvalidDynamicBlockHeader); | 1030 | try testFailure(.raw, @embedFile("testdata/fuzz/puff26.input"), error.InvalidDynamicBlockHeader); |
| 1025 | } | 1031 | } |
| 1026 | test "failing puff27" { | 1032 | test "failing puff27" { |
| 1027 | try testFailure(@embedFile("testdata/fuzz/puff27.input"), error.InvalidDynamicBlockHeader); | 1033 | try testFailure(.raw, @embedFile("testdata/fuzz/puff27.input"), error.InvalidDynamicBlockHeader); |
| 1028 | } | | |
| 1029 | | | |
| 1030 | fn testFailure(in: []const u8, expected_err: anyerror) !void { | | |
| 1031 | var reader: Reader = .fixed(in); | | |
| 1032 | var aw: Writer.Allocating = .init(testing.allocator); | | |
| 1033 | try aw.ensureUnusedCapacity(flate.history_len); | | |
| 1034 | defer aw.deinit(); | | |
| 1035 | | | |
| 1036 | var decompress: Decompress = .init(&reader, .raw, &.{}); | | |
| 1037 | try testing.expectError(error.ReadFailed, decompress.reader.streamRemaining(&aw.writer)); | | |
| 1038 | try testing.expectEqual(expected_err, decompress.read_err orelse return error.TestFailed); | | |
| 1039 | } | 1034 | } |
| 1040 | | 1035 | |
| 1041 | test "deflate-stream" { | 1036 | test "deflate-stream" { |
| ... | @@ -1097,82 +1092,57 @@ test "don't read past deflate stream's end" { | ... | @@ -1097,82 +1092,57 @@ test "don't read past deflate stream's end" { |
| 1097 | | 1092 | |
| 1098 | test "zlib header" { | 1093 | test "zlib header" { |
| 1099 | // Truncated header | 1094 | // Truncated header |
| 1100 | try testing.expectError( | 1095 | try testFailure(.zlib, &[_]u8{0x78}, error.EndOfStream); |
| 1101 | error.EndOfStream, | 1096 | |
| 1102 | testDecompress(.zlib, &[_]u8{0x78}, ""), | | |
| 1103 | ); | | |
| 1104 | // Wrong CM | 1097 | // Wrong CM |
| 1105 | try testing.expectError( | 1098 | try testFailure(.zlib, &[_]u8{ 0x79, 0x94 }, error.BadZlibHeader); |
| 1106 | error.BadZlibHeader, | 1099 | |
| 1107 | testDecompress(.zlib, &[_]u8{ 0x79, 0x94 }, ""), | | |
| 1108 | ); | | |
| 1109 | // Wrong CINFO | 1100 | // Wrong CINFO |
| 1110 | try testing.expectError( | 1101 | try testFailure(.zlib, &[_]u8{ 0x88, 0x98 }, error.BadZlibHeader); |
| 1111 | error.BadZlibHeader, | 1102 | |
| 1112 | testDecompress(.zlib, &[_]u8{ 0x88, 0x98 }, ""), | | |
| 1113 | ); | | |
| 1114 | // Wrong checksum | 1103 | // Wrong checksum |
| 1115 | try testing.expectError( | 1104 | try testFailure(.zlib, &[_]u8{ 0x78, 0xda, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, error.WrongZlibChecksum); |
| 1116 | error.WrongZlibChecksum, | 1105 | |
| 1117 | testDecompress(.zlib, &[_]u8{ 0x78, 0xda, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 }, ""), | | |
| 1118 | ); | | |
| 1119 | // Truncated checksum | 1106 | // Truncated checksum |
| 1120 | try testing.expectError( | 1107 | try testFailure(.zlib, &[_]u8{ 0x78, 0xda, 0x03, 0x00, 0x00 }, error.EndOfStream); |
| 1121 | error.EndOfStream, | | |
| 1122 | testDecompress(.zlib, &[_]u8{ 0x78, 0xda, 0x03, 0x00, 0x00 }, ""), | | |
| 1123 | ); | | |
| 1124 | } | 1108 | } |
| 1125 | | 1109 | |
| 1126 | test "gzip header" { | 1110 | test "gzip header" { |
| 1127 | // Truncated header | 1111 | // Truncated header |
| 1128 | try testing.expectError( | 1112 | try testFailure(.gzip, &[_]u8{ 0x1f, 0x8B }, error.EndOfStream); |
| 1129 | error.EndOfStream, | 1113 | |
| 1130 | testDecompress(.gzip, &[_]u8{ 0x1f, 0x8B }, undefined), | | |
| 1131 | ); | | |
| 1132 | // Wrong CM | 1114 | // Wrong CM |
| 1133 | try testing.expectError( | 1115 | try testFailure(.gzip, &[_]u8{ |
| 1134 | error.BadGzipHeader, | 1116 | 0x1f, 0x8b, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 1135 | testDecompress(.gzip, &[_]u8{ | 1117 | 0x00, 0x03, |
| 1136 | 0x1f, 0x8b, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, | 1118 | }, error.BadGzipHeader); |
| 1137 | 0x00, 0x03, | | |
| 1138 | }, undefined), | | |
| 1139 | ); | | |
| 1140 | | 1119 | |
| 1141 | // Wrong checksum | 1120 | // Wrong checksum |
| 1142 | try testing.expectError( | 1121 | try testFailure(.gzip, &[_]u8{ |
| 1143 | error.WrongGzipChecksum, | 1122 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 1144 | testDecompress(.gzip, &[_]u8{ | 1123 | 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, |
| 1145 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, | 1124 | 0x00, 0x00, 0x00, 0x00, |
| 1146 | 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, | 1125 | }, error.WrongGzipChecksum); |
| 1147 | 0x00, 0x00, 0x00, 0x00, | 1126 | |
| 1148 | }, undefined), | | |
| 1149 | ); | | |
| 1150 | // Truncated checksum | 1127 | // Truncated checksum |
| 1151 | try testing.expectError( | 1128 | try testFailure(.gzip, &[_]u8{ |
| 1152 | error.EndOfStream, | 1129 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 1153 | testDecompress(.gzip, &[_]u8{ | 1130 | 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, |
| 1154 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, | 1131 | }, error.EndOfStream); |
| 1155 | 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, | 1132 | |
| 1156 | }, undefined), | | |
| 1157 | ); | | |
| 1158 | // Wrong initial size | 1133 | // Wrong initial size |
| 1159 | try testing.expectError( | 1134 | try testFailure(.gzip, &[_]u8{ |
| 1160 | error.WrongGzipSize, | 1135 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 1161 | testDecompress(.gzip, &[_]u8{ | 1136 | 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 1162 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, | 1137 | 0x00, 0x00, 0x00, 0x01, |
| 1163 | 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, | 1138 | }, error.WrongGzipSize); |
| 1164 | 0x00, 0x00, 0x00, 0x01, | 1139 | |
| 1165 | }, undefined), | | |
| 1166 | ); | | |
| 1167 | // Truncated initial size field | 1140 | // Truncated initial size field |
| 1168 | try testing.expectError( | 1141 | try testFailure(.gzip, &[_]u8{ |
| 1169 | error.EndOfStream, | 1142 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 1170 | testDecompress(.gzip, &[_]u8{ | 1143 | 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 1171 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, | 1144 | 0x00, 0x00, 0x00, |
| 1172 | 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, | 1145 | }, error.EndOfStream); |
| 1173 | 0x00, 0x00, 0x00, | | |
| 1174 | }, undefined), | | |
| 1175 | ); | | |
| 1176 | | 1146 | |
| 1177 | try testDecompress(.gzip, &[_]u8{ | 1147 | try testDecompress(.gzip, &[_]u8{ |
| 1178 | // GZIP header | 1148 | // GZIP header |
| ... | @@ -1184,17 +1154,6 @@ test "gzip header" { | ... | @@ -1184,17 +1154,6 @@ test "gzip header" { |
| 1184 | }, ""); | 1154 | }, ""); |
| 1185 | } | 1155 | } |
| 1186 | | 1156 | |
| 1187 | fn testDecompress(container: Container, compressed: []const u8, expected_plain: []const u8) !void { | | |
| 1188 | var in: std.Io.Reader = .fixed(compressed); | | |
| 1189 | var aw: std.Io.Writer.Allocating = .init(testing.allocator); | | |
| 1190 | try aw.ensureUnusedCapacity(flate.history_len); | | |
| 1191 | defer aw.deinit(); | | |
| 1192 | | | |
| 1193 | var decompress: Decompress = .init(&in, container, &.{}); | | |
| 1194 | _ = try decompress.reader.streamRemaining(&aw.writer); | | |
| 1195 | try testing.expectEqualSlices(u8, expected_plain, aw.getWritten()); | | |
| 1196 | } | | |
| 1197 | | | |
| 1198 | test "zlib should not overshoot" { | 1157 | test "zlib should not overshoot" { |
| 1199 | // Compressed zlib data with extra 4 bytes at the end. | 1158 | // Compressed zlib data with extra 4 bytes at the end. |
| 1200 | const data = [_]u8{ | 1159 | const data = [_]u8{ |
| ... | @@ -1220,3 +1179,25 @@ test "zlib should not overshoot" { | ... | @@ -1220,3 +1179,25 @@ test "zlib should not overshoot" { |
| 1220 | try std.testing.expectEqual(n, 4); | 1179 | try std.testing.expectEqual(n, 4); |
| 1221 | try std.testing.expectEqualSlices(u8, data[data.len - 4 .. data.len], out[0..n]); | 1180 | try std.testing.expectEqualSlices(u8, data[data.len - 4 .. data.len], out[0..n]); |
| 1222 | } | 1181 | } |
| | 1182 | |
| | 1183 | fn testFailure(container: Container, in: []const u8, expected_err: anyerror) !void { |
| | 1184 | var reader: Reader = .fixed(in); |
| | 1185 | var aw: Writer.Allocating = .init(testing.allocator); |
| | 1186 | try aw.ensureUnusedCapacity(flate.history_len); |
| | 1187 | defer aw.deinit(); |
| | 1188 | |
| | 1189 | var decompress: Decompress = .init(&reader, container, &.{}); |
| | 1190 | try testing.expectError(error.ReadFailed, decompress.reader.streamRemaining(&aw.writer)); |
| | 1191 | try testing.expectEqual(expected_err, decompress.read_err orelse return error.TestFailed); |
| | 1192 | } |
| | 1193 | |
| | 1194 | fn testDecompress(container: Container, compressed: []const u8, expected_plain: []const u8) !void { |
| | 1195 | var in: std.Io.Reader = .fixed(compressed); |
| | 1196 | var aw: std.Io.Writer.Allocating = .init(testing.allocator); |
| | 1197 | try aw.ensureUnusedCapacity(flate.history_len); |
| | 1198 | defer aw.deinit(); |
| | 1199 | |
| | 1200 | var decompress: Decompress = .init(&in, container, &.{}); |
| | 1201 | _ = try decompress.reader.streamRemaining(&aw.writer); |
| | 1202 | try testing.expectEqualSlices(u8, expected_plain, aw.getWritten()); |
| | 1203 | } |