135 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			V
		
	
	
			
		
		
	
	
			135 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			V
		
	
	
module gzip
 | 
						|
 | 
						|
import hash.crc32
 | 
						|
 | 
						|
fn test_gzip() ? {
 | 
						|
	uncompressed := 'Hello world!'
 | 
						|
	compressed := compress(uncompressed.bytes())?
 | 
						|
	decompressed := decompress(compressed)?
 | 
						|
	assert decompressed == uncompressed.bytes()
 | 
						|
}
 | 
						|
 | 
						|
fn assert_decompress_error(data []u8, reason string) ? {
 | 
						|
	decompress(data) or {
 | 
						|
		assert err.msg() == reason
 | 
						|
		return
 | 
						|
	}
 | 
						|
	return error('did not error')
 | 
						|
}
 | 
						|
 | 
						|
fn test_gzip_invalid_too_short() ? {
 | 
						|
	assert_decompress_error([]u8{}, 'data is too short, not gzip compressed?')?
 | 
						|
}
 | 
						|
 | 
						|
fn test_gzip_invalid_magic_numbers() ? {
 | 
						|
	assert_decompress_error([]u8{len: 100}, 'wrong magic numbers, not gzip compressed?')?
 | 
						|
}
 | 
						|
 | 
						|
fn test_gzip_invalid_compression() ? {
 | 
						|
	mut data := []u8{len: 100}
 | 
						|
	data[0] = 0x1f
 | 
						|
	data[1] = 0x8b
 | 
						|
	assert_decompress_error(data, 'gzip data is not compressed with DEFLATE')?
 | 
						|
}
 | 
						|
 | 
						|
fn test_gzip_with_ftext() ? {
 | 
						|
	uncompressed := 'Hello world!'
 | 
						|
	mut compressed := compress(uncompressed.bytes())?
 | 
						|
	compressed[4] |= 0b0000_0001 // FTEXT
 | 
						|
	decompressed := decompress(compressed)?
 | 
						|
	assert decompressed == uncompressed.bytes()
 | 
						|
}
 | 
						|
 | 
						|
fn test_gzip_with_fname() ? {
 | 
						|
	uncompressed := 'Hello world!'
 | 
						|
	mut compressed := compress(uncompressed.bytes())?
 | 
						|
	compressed[4] |= 0b0000_1000
 | 
						|
	compressed.insert(10, `h`)
 | 
						|
	compressed.insert(11, `i`)
 | 
						|
	compressed.insert(12, 0x00)
 | 
						|
	decompressed := decompress(compressed)?
 | 
						|
	assert decompressed == uncompressed.bytes()
 | 
						|
}
 | 
						|
 | 
						|
fn test_gzip_with_fcomment() ? {
 | 
						|
	uncompressed := 'Hello world!'
 | 
						|
	mut compressed := compress(uncompressed.bytes())?
 | 
						|
	compressed[4] |= 0b0001_0000
 | 
						|
	compressed.insert(10, `h`)
 | 
						|
	compressed.insert(11, `i`)
 | 
						|
	compressed.insert(12, 0x00)
 | 
						|
	decompressed := decompress(compressed)?
 | 
						|
	assert decompressed == uncompressed.bytes()
 | 
						|
}
 | 
						|
 | 
						|
fn test_gzip_with_fname_fcomment() ? {
 | 
						|
	uncompressed := 'Hello world!'
 | 
						|
	mut compressed := compress(uncompressed.bytes())?
 | 
						|
	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)
 | 
						|
	decompressed := decompress(compressed)?
 | 
						|
	assert decompressed == uncompressed.bytes()
 | 
						|
}
 | 
						|
 | 
						|
fn test_gzip_with_fextra() ? {
 | 
						|
	uncompressed := 'Hello world!'
 | 
						|
	mut compressed := compress(uncompressed.bytes())?
 | 
						|
	compressed[4] |= 0b0000_0100
 | 
						|
	compressed.insert(10, 2)
 | 
						|
	compressed.insert(11, `h`)
 | 
						|
	compressed.insert(12, `i`)
 | 
						|
	decompressed := decompress(compressed)?
 | 
						|
	assert decompressed == uncompressed.bytes()
 | 
						|
}
 | 
						|
 | 
						|
fn test_gzip_with_hcrc() ? {
 | 
						|
	uncompressed := 'Hello world!'
 | 
						|
	mut compressed := compress(uncompressed.bytes())?
 | 
						|
	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))
 | 
						|
	decompressed := decompress(compressed)?
 | 
						|
	assert decompressed == uncompressed.bytes()
 | 
						|
}
 | 
						|
 | 
						|
fn test_gzip_with_invalid_hcrc() ? {
 | 
						|
	uncompressed := 'Hello world!'
 | 
						|
	mut compressed := compress(uncompressed.bytes())?
 | 
						|
	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))
 | 
						|
	assert_decompress_error(compressed, 'header checksum verification failed')?
 | 
						|
}
 | 
						|
 | 
						|
fn test_gzip_with_invalid_checksum() ? {
 | 
						|
	uncompressed := 'Hello world!'
 | 
						|
	mut compressed := compress(uncompressed.bytes())?
 | 
						|
	compressed[compressed.len - 5] += 1
 | 
						|
	assert_decompress_error(compressed, 'checksum verification failed')?
 | 
						|
}
 | 
						|
 | 
						|
fn test_gzip_with_invalid_length() ? {
 | 
						|
	uncompressed := 'Hello world!'
 | 
						|
	mut compressed := compress(uncompressed.bytes())?
 | 
						|
	compressed[compressed.len - 1] += 1
 | 
						|
	assert_decompress_error(compressed, 'length verification failed, got 12, expected 13')?
 | 
						|
}
 | 
						|
 | 
						|
fn test_gzip_with_invalid_flags() ? {
 | 
						|
	uncompressed := 'Hello world!'
 | 
						|
	mut compressed := compress(uncompressed.bytes())?
 | 
						|
	compressed[4] |= 0b1000_0000
 | 
						|
	assert_decompress_error(compressed, 'reserved flags are set, unsupported field detected')?
 | 
						|
}
 |