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