A sweep found no defect in the decoder and several in its tests. Three of the five fixes could be reverted with all 103 tests still green. The content size against expectedSize check is the worst of those, because the .hgtz reader was simplified to rest on it: deleting it left everything passing. Eleven cases cover it now. The RLE block ceiling and the requirement that a frame be the whole input had none either, so there are fixtures for a 13-byte frame that returns 2 MB, for the same shape at exactly the maximum, for four bytes of junk after a frame, and for a trailing skippable frame. Two of the new fixtures close coverage gaps rather than guards. No legal frame in the suite decoded a one-stream Huffman literals section, since the only one present had to be refused. And the only test of hashing each block as it lands rode on the zstd CLI being installed, so a multi-block frame carrying a checksum is committed now. Also replaces an assertion that constrained nothing. "Fills the buffer exactly" checked that the count was over 256 and under 1024, which passes with the guard at two, at three, or absent. The stream encodes 257 symbols, a buffer of 257 takes it and one of 256 does not. And two comments that were wrong. The weight buffer is one larger than the maximum on purpose, and shrinking it to 255 breaks 124 tests. A caller passing expectedSize gets the exact check in addition to the ceiling, not instead of it.
63 lines
2.6 KiB
Dart
63 lines
2.6 KiB
Dart
import 'dart:typed_data';
|
|
|
|
import 'package:pure_zstd/src/bit_reader.dart';
|
|
import 'package:pure_zstd/src/exception.dart';
|
|
import 'package:pure_zstd/src/fse.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
/// `fseDecodeInterleaved` has no symbol count to stop on: it runs until the
|
|
/// bitstream is spent, so the only thing keeping it inside the caller's
|
|
/// buffer is its own room check. Both of its exhausted branches write a third
|
|
/// symbol in the same pass, so a check for two let `at` reach `outLimit`,
|
|
/// which is one past the end.
|
|
///
|
|
/// `HuffmanTable` calls it with a 256-byte buffer, so overrunning it indexes
|
|
/// `_weights[256]`. This is the same reproducer as the 53-byte frame in the
|
|
/// corpus, with the frame stripped away: the weight table description and the
|
|
/// bitstream the block carried, handed straight to the function.
|
|
void main() {
|
|
group('fseDecodeInterleaved', () {
|
|
// The two bytes are the whole FSE table description: accuracy log 5 and a
|
|
// distribution that gives the stream below two symbols per state pair.
|
|
final description = Uint8List.fromList([0x10, 0x3F]);
|
|
|
|
// 33 bytes of 0xAA and then the end marker, which is the stream the
|
|
// crafted block put after the description.
|
|
final stream = Uint8List.fromList([...List.filled(33, 0xAA), 0x02]);
|
|
|
|
test('refuses a stream longer than the caller has room for', () {
|
|
final table = FseTable(6);
|
|
expect(readFseTable(table, description, 0, description.length, 255), 2);
|
|
|
|
final bits = ReverseBitReader()..reset(stream, 0, stream.length);
|
|
final weights = Uint8List(256);
|
|
|
|
expect(
|
|
() => fseDecodeInterleaved(table, bits, weights, 0, weights.length),
|
|
throwsA(isA<ZstdException>()),
|
|
);
|
|
});
|
|
|
|
test(
|
|
'writes exactly what the stream encodes, and knows where that ends',
|
|
() {
|
|
// The old version of this asserted only that the count was over 256
|
|
// and under 1024, which passes with the guard at `at + 2`, at
|
|
// `at + 3`, or removed entirely. This stream encodes 257 symbols, and
|
|
// the boundary is the whole point: a buffer of exactly 257 takes it
|
|
// and one of 256 does not.
|
|
int run(int limit) {
|
|
final table = FseTable(6);
|
|
readFseTable(table, description, 0, description.length, 255);
|
|
final bits = ReverseBitReader()..reset(stream, 0, stream.length);
|
|
|
|
return fseDecodeInterleaved(table, bits, Uint8List(1024), 0, limit);
|
|
}
|
|
|
|
expect(run(1024), 257);
|
|
expect(run(257), 257);
|
|
expect(() => run(256), throwsA(isA<ZstdException>()));
|
|
},
|
|
);
|
|
});
|
|
}
|