2022-06-05 18:53:45 +03:00
|
|
|
module gzip
|
|
|
|
|
|
|
|
import hash.crc32
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip() {
|
2022-06-05 18:53:45 +03:00
|
|
|
uncompressed := 'Hello world!'
|
2022-10-20 22:14:33 +03:00
|
|
|
compressed := compress(uncompressed.bytes())!
|
|
|
|
decompressed := decompress(compressed)!
|
2022-06-05 18:53:45 +03:00
|
|
|
assert decompressed == uncompressed.bytes()
|
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn assert_decompress_error(data []u8, reason string) ! {
|
2022-06-05 18:53:45 +03:00
|
|
|
decompress(data) or {
|
|
|
|
assert err.msg() == reason
|
|
|
|
return
|
|
|
|
}
|
|
|
|
return error('did not error')
|
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip_invalid_too_short() {
|
|
|
|
assert_decompress_error([]u8{}, 'data is too short, not gzip compressed?')!
|
2022-06-05 18:53:45 +03:00
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip_invalid_magic_numbers() {
|
|
|
|
assert_decompress_error([]u8{len: 100}, 'wrong magic numbers, not gzip compressed?')!
|
2022-06-05 18:53:45 +03:00
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip_invalid_compression() {
|
2022-06-05 18:53:45 +03:00
|
|
|
mut data := []u8{len: 100}
|
|
|
|
data[0] = 0x1f
|
|
|
|
data[1] = 0x8b
|
2022-10-20 22:14:33 +03:00
|
|
|
assert_decompress_error(data, 'gzip data is not compressed with DEFLATE')!
|
2022-06-05 18:53:45 +03:00
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip_with_ftext() {
|
2022-06-05 18:53:45 +03:00
|
|
|
uncompressed := 'Hello world!'
|
2022-10-20 22:14:33 +03:00
|
|
|
mut compressed := compress(uncompressed.bytes())!
|
2022-06-05 18:53:45 +03:00
|
|
|
compressed[4] |= 0b0000_0001 // FTEXT
|
2022-10-20 22:14:33 +03:00
|
|
|
decompressed := decompress(compressed)!
|
2022-06-05 18:53:45 +03:00
|
|
|
assert decompressed == uncompressed.bytes()
|
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip_with_fname() {
|
2022-06-05 18:53:45 +03:00
|
|
|
uncompressed := 'Hello world!'
|
2022-10-20 22:14:33 +03:00
|
|
|
mut compressed := compress(uncompressed.bytes())!
|
2022-06-05 18:53:45 +03:00
|
|
|
compressed[4] |= 0b0000_1000
|
|
|
|
compressed.insert(10, `h`)
|
|
|
|
compressed.insert(11, `i`)
|
|
|
|
compressed.insert(12, 0x00)
|
2022-10-20 22:14:33 +03:00
|
|
|
decompressed := decompress(compressed)!
|
2022-06-05 18:53:45 +03:00
|
|
|
assert decompressed == uncompressed.bytes()
|
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip_with_fcomment() {
|
2022-06-05 18:53:45 +03:00
|
|
|
uncompressed := 'Hello world!'
|
2022-10-20 22:14:33 +03:00
|
|
|
mut compressed := compress(uncompressed.bytes())!
|
2022-06-05 18:53:45 +03:00
|
|
|
compressed[4] |= 0b0001_0000
|
|
|
|
compressed.insert(10, `h`)
|
|
|
|
compressed.insert(11, `i`)
|
|
|
|
compressed.insert(12, 0x00)
|
2022-10-20 22:14:33 +03:00
|
|
|
decompressed := decompress(compressed)!
|
2022-06-05 18:53:45 +03:00
|
|
|
assert decompressed == uncompressed.bytes()
|
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip_with_fname_fcomment() {
|
2022-06-05 18:53:45 +03:00
|
|
|
uncompressed := 'Hello world!'
|
2022-10-20 22:14:33 +03:00
|
|
|
mut compressed := compress(uncompressed.bytes())!
|
2022-06-05 18:53:45 +03:00
|
|
|
compressed[4] |= 0b0001_1000
|
|
|
|
compressed.insert(10, `h`)
|
|
|
|
compressed.insert(11, `i`)
|
|
|
|
compressed.insert(12, 0x00)
|
|
|
|
compressed.insert(10, `h`)
|
|
|
|
compressed.insert(11, `i`)
|
|
|
|
compressed.insert(12, 0x00)
|
2022-10-20 22:14:33 +03:00
|
|
|
decompressed := decompress(compressed)!
|
2022-06-05 18:53:45 +03:00
|
|
|
assert decompressed == uncompressed.bytes()
|
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip_with_fextra() {
|
2022-06-05 18:53:45 +03:00
|
|
|
uncompressed := 'Hello world!'
|
2022-10-20 22:14:33 +03:00
|
|
|
mut compressed := compress(uncompressed.bytes())!
|
2022-06-05 18:53:45 +03:00
|
|
|
compressed[4] |= 0b0000_0100
|
|
|
|
compressed.insert(10, 2)
|
|
|
|
compressed.insert(11, `h`)
|
|
|
|
compressed.insert(12, `i`)
|
2022-10-20 22:14:33 +03:00
|
|
|
decompressed := decompress(compressed)!
|
2022-06-05 18:53:45 +03:00
|
|
|
assert decompressed == uncompressed.bytes()
|
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip_with_hcrc() {
|
2022-06-05 18:53:45 +03:00
|
|
|
uncompressed := 'Hello world!'
|
2022-10-20 22:14:33 +03:00
|
|
|
mut compressed := compress(uncompressed.bytes())!
|
2022-06-05 18:53:45 +03:00
|
|
|
compressed[4] |= 0b0000_0010
|
|
|
|
checksum := crc32.sum(compressed[..10])
|
|
|
|
compressed.insert(10, u8(checksum >> 24))
|
|
|
|
compressed.insert(11, u8(checksum >> 16))
|
|
|
|
compressed.insert(12, u8(checksum >> 8))
|
|
|
|
compressed.insert(13, u8(checksum))
|
2022-10-20 22:14:33 +03:00
|
|
|
decompressed := decompress(compressed)!
|
2022-06-05 18:53:45 +03:00
|
|
|
assert decompressed == uncompressed.bytes()
|
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip_with_invalid_hcrc() {
|
2022-06-05 18:53:45 +03:00
|
|
|
uncompressed := 'Hello world!'
|
2022-10-20 22:14:33 +03:00
|
|
|
mut compressed := compress(uncompressed.bytes())!
|
2022-06-05 18:53:45 +03:00
|
|
|
compressed[4] |= 0b0000_0010
|
|
|
|
checksum := crc32.sum(compressed[..10])
|
|
|
|
compressed.insert(10, u8(checksum >> 24))
|
|
|
|
compressed.insert(11, u8(checksum >> 16))
|
|
|
|
compressed.insert(12, u8(checksum >> 8))
|
|
|
|
compressed.insert(13, u8(checksum + 1))
|
2022-10-20 22:14:33 +03:00
|
|
|
assert_decompress_error(compressed, 'header checksum verification failed')!
|
2022-06-05 18:53:45 +03:00
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip_with_invalid_checksum() {
|
2022-06-05 18:53:45 +03:00
|
|
|
uncompressed := 'Hello world!'
|
2022-10-20 22:14:33 +03:00
|
|
|
mut compressed := compress(uncompressed.bytes())!
|
2022-06-05 18:53:45 +03:00
|
|
|
compressed[compressed.len - 5] += 1
|
2022-10-20 22:14:33 +03:00
|
|
|
assert_decompress_error(compressed, 'checksum verification failed')!
|
2022-06-05 18:53:45 +03:00
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip_with_invalid_length() {
|
2022-06-05 18:53:45 +03:00
|
|
|
uncompressed := 'Hello world!'
|
2022-10-20 22:14:33 +03:00
|
|
|
mut compressed := compress(uncompressed.bytes())!
|
2022-06-05 18:53:45 +03:00
|
|
|
compressed[compressed.len - 1] += 1
|
2022-10-20 22:14:33 +03:00
|
|
|
assert_decompress_error(compressed, 'length verification failed, got 12, expected 13')!
|
2022-06-05 18:53:45 +03:00
|
|
|
}
|
|
|
|
|
2022-10-20 22:14:33 +03:00
|
|
|
fn test_gzip_with_invalid_flags() {
|
2022-06-05 18:53:45 +03:00
|
|
|
uncompressed := 'Hello world!'
|
2022-10-20 22:14:33 +03:00
|
|
|
mut compressed := compress(uncompressed.bytes())!
|
2022-06-05 18:53:45 +03:00
|
|
|
compressed[4] |= 0b1000_0000
|
2022-10-20 22:14:33 +03:00
|
|
|
assert_decompress_error(compressed, 'reserved flags are set, unsupported field detected')!
|
2022-06-05 18:53:45 +03:00
|
|
|
}
|