xref: /netbsd-src/external/public-domain/xz/dist/tests/test_stream_flags.c (revision 4d1abfb29e19727d8dfeef21d710fb741c73ec34)
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       test_stream_flags.c
4 /// \brief      Tests Stream Header and Stream Footer coders
5 //
6 //  Author:     Lasse Collin
7 //
8 //  This file has been put into the public domain.
9 //  You can do whatever you want with this file.
10 //
11 ///////////////////////////////////////////////////////////////////////////////
12 
13 #include "tests.h"
14 
15 
16 static lzma_stream_flags known_flags;
17 static lzma_stream_flags decoded_flags;
18 static uint8_t buffer[LZMA_STREAM_HEADER_SIZE];
19 
20 
21 static bool
validate(void)22 validate(void)
23 {
24 	// TODO: This could require the specific error type as an argument.
25 	// We could also test that lzma_stream_flags_compare() gives
26 	// the correct return values in different situations.
27 	return lzma_stream_flags_compare(&known_flags, &decoded_flags)
28 			!= LZMA_OK;
29 }
30 
31 
32 static bool
test_header_decoder(lzma_ret expected_ret)33 test_header_decoder(lzma_ret expected_ret)
34 {
35 	memcrap(&decoded_flags, sizeof(decoded_flags));
36 
37 	if (lzma_stream_header_decode(&decoded_flags, buffer) != expected_ret)
38 		return true;
39 
40 	if (expected_ret != LZMA_OK)
41 		return false;
42 
43 	// Header doesn't have Backward Size, so make
44 	// lzma_stream_flags_compare() ignore it.
45 	decoded_flags.backward_size = LZMA_VLI_UNKNOWN;
46 	return validate();
47 }
48 
49 
50 static void
test_header(void)51 test_header(void)
52 {
53 	memcrap(buffer, sizeof(buffer));
54 	expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);
55 	succeed(test_header_decoder(LZMA_OK));
56 }
57 
58 
59 static bool
test_footer_decoder(lzma_ret expected_ret)60 test_footer_decoder(lzma_ret expected_ret)
61 {
62 	memcrap(&decoded_flags, sizeof(decoded_flags));
63 
64 	if (lzma_stream_footer_decode(&decoded_flags, buffer) != expected_ret)
65 		return true;
66 
67 	if (expected_ret != LZMA_OK)
68 		return false;
69 
70 	return validate();
71 }
72 
73 
74 static void
test_footer(void)75 test_footer(void)
76 {
77 	memcrap(buffer, sizeof(buffer));
78 	expect(lzma_stream_footer_encode(&known_flags, buffer) == LZMA_OK);
79 	succeed(test_footer_decoder(LZMA_OK));
80 }
81 
82 
83 static void
test_encode_invalid(void)84 test_encode_invalid(void)
85 {
86 	known_flags.check = LZMA_CHECK_ID_MAX + 1;
87 	known_flags.backward_size = 1024;
88 
89 	expect(lzma_stream_header_encode(&known_flags, buffer)
90 			== LZMA_PROG_ERROR);
91 
92 	expect(lzma_stream_footer_encode(&known_flags, buffer)
93 			== LZMA_PROG_ERROR);
94 
95 	known_flags.check = (lzma_check)(-1);
96 
97 	expect(lzma_stream_header_encode(&known_flags, buffer)
98 			== LZMA_PROG_ERROR);
99 
100 	expect(lzma_stream_footer_encode(&known_flags, buffer)
101 			== LZMA_PROG_ERROR);
102 
103 	known_flags.check = LZMA_CHECK_NONE;
104 	known_flags.backward_size = 0;
105 
106 	// Header encoder ignores backward_size.
107 	expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);
108 
109 	expect(lzma_stream_footer_encode(&known_flags, buffer)
110 			== LZMA_PROG_ERROR);
111 
112 	known_flags.backward_size = LZMA_VLI_MAX;
113 
114 	expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);
115 
116 	expect(lzma_stream_footer_encode(&known_flags, buffer)
117 			== LZMA_PROG_ERROR);
118 }
119 
120 
121 static void
test_decode_invalid(void)122 test_decode_invalid(void)
123 {
124 	known_flags.check = LZMA_CHECK_NONE;
125 	known_flags.backward_size = 1024;
126 
127 	expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);
128 
129 	// Test 1 (invalid Magic Bytes)
130 	buffer[5] ^= 1;
131 	succeed(test_header_decoder(LZMA_FORMAT_ERROR));
132 	buffer[5] ^= 1;
133 
134 	// Test 2a (valid CRC32)
135 	uint32_t crc = lzma_crc32(buffer + 6, 2, 0);
136 	unaligned_write32le(buffer + 8, crc);
137 	succeed(test_header_decoder(LZMA_OK));
138 
139 	// Test 2b (invalid Stream Flags with valid CRC32)
140 	buffer[6] ^= 0x20;
141 	crc = lzma_crc32(buffer + 6, 2, 0);
142 	unaligned_write32le(buffer + 8, crc);
143 	succeed(test_header_decoder(LZMA_OPTIONS_ERROR));
144 
145 	// Test 3 (invalid CRC32)
146 	expect(lzma_stream_header_encode(&known_flags, buffer) == LZMA_OK);
147 	buffer[9] ^= 1;
148 	succeed(test_header_decoder(LZMA_DATA_ERROR));
149 
150 	// Test 4 (invalid Stream Flags with valid CRC32)
151 	expect(lzma_stream_footer_encode(&known_flags, buffer) == LZMA_OK);
152 	buffer[9] ^= 0x40;
153 	crc = lzma_crc32(buffer + 4, 6, 0);
154 	unaligned_write32le(buffer, crc);
155 	succeed(test_footer_decoder(LZMA_OPTIONS_ERROR));
156 
157 	// Test 5 (invalid Magic Bytes)
158 	expect(lzma_stream_footer_encode(&known_flags, buffer) == LZMA_OK);
159 	buffer[11] ^= 1;
160 	succeed(test_footer_decoder(LZMA_FORMAT_ERROR));
161 }
162 
163 
164 int
main(void)165 main(void)
166 {
167 	// Valid headers
168 	known_flags.backward_size = 1024;
169 	for (lzma_check check = LZMA_CHECK_NONE;
170 			check <= LZMA_CHECK_ID_MAX; ++check) {
171 		test_header();
172 		test_footer();
173 	}
174 
175 	// Invalid headers
176 	test_encode_invalid();
177 	test_decode_invalid();
178 
179 	return 0;
180 }
181