45b20db00118a5d155d4fbcd4ff2e865f726c3c5
[strongswan.git] / src / libstrongswan / tests / test_bio_reader.c
1 /*
2 * Copyright (C) 2013 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "test_suite.h"
17
18 #include <bio/bio_reader.h>
19
20 /*******************************************************************************
21 * different integer reads
22 */
23
24 #define assert_integer_read(data, bits, val) ({ \
25 bio_reader_t *reader = bio_reader_create(data); \
26 typeof(val) i; \
27 for (i = 0; reader->remaining(reader) >= (bits / 8); i++) \
28 { \
29 ck_assert(reader->read_uint##bits(reader, &val)); \
30 ck_assert_int_eq(i, val); \
31 } \
32 ck_assert_int_eq(i, data.len / (bits / 8)); \
33 ck_assert_int_eq(reader->remaining(reader), data.len % (bits / 8)); \
34 ck_assert(!reader->read_uint##bits(reader, &val)); \
35 reader->destroy(reader); \
36 })
37
38 #define assert_integer_read_uneven(data, bits, val) ({ \
39 int i; \
40 for (i = 0; i <= bits / 8; i++, data.len++) \
41 { \
42 assert_integer_read(data, bits, val); \
43 } \
44 })
45
46 #define assert_basic_read(bits, val) ({ \
47 chunk_t data; \
48 data = chunk_empty; \
49 assert_integer_read(data, bits, val); \
50 data = chunk_alloca(bits / 8); \
51 memset(data.ptr, 0, data.len); \
52 data.len = 0; \
53 assert_integer_read_uneven(data, bits, val); \
54 })
55
56 #define assert_extended_read(data, bits, val) ({ \
57 chunk_t extended = chunk_alloca(data.len + bits / 8); \
58 memset(extended.ptr, 0, extended.len); \
59 extended.ptr[extended.len - 1] = data.len / (bits / 8); \
60 memcpy(extended.ptr, data.ptr, data.len); \
61 extended.len = data.len; \
62 assert_integer_read_uneven(extended, bits, val); \
63 })
64
65 START_TEST(test_read_uint8)
66 {
67 chunk_t data = chunk_from_chars(0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07);
68 u_int8_t val;
69
70 assert_integer_read(data, 8, val);
71 assert_basic_read(8, val);
72 assert_extended_read(data, 8, val);
73 }
74 END_TEST
75
76 START_TEST(test_read_uint16)
77 {
78 chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03);
79 u_int16_t val;
80
81 assert_integer_read(data, 16, val);
82 assert_basic_read(16, val);
83 assert_extended_read(data, 16, val);
84 }
85 END_TEST
86
87 START_TEST(test_read_uint24)
88 {
89 chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03);
90 u_int32_t val;
91
92 assert_integer_read(data, 24, val);
93 assert_basic_read(24, val);
94 assert_extended_read(data, 24, val);
95 }
96 END_TEST
97
98 START_TEST(test_read_uint32)
99 {
100 chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
101 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03);
102 u_int32_t val;
103
104 assert_integer_read(data, 32, val);
105 assert_basic_read(32, val);
106 assert_extended_read(data, 32, val);
107 }
108 END_TEST
109
110 START_TEST(test_read_uint64)
111 {
112 chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03);
116 u_int64_t val;
117
118 assert_integer_read(data, 64, val);
119 assert_basic_read(64, val);
120 assert_extended_read(data, 64, val);
121 }
122 END_TEST
123
124 /*******************************************************************************
125 * different integer reads from the end of a buffer
126 */
127
128 #define assert_integer_read_end(data, bits, val) ({ \
129 bio_reader_t *reader = bio_reader_create(data); \
130 typeof(val) i; \
131 for (i = 0; reader->remaining(reader) >= (bits / 8); i++) \
132 { \
133 ck_assert(reader->read_uint##bits##_end(reader, &val)); \
134 ck_assert_int_eq(i, val); \
135 } \
136 ck_assert_int_eq(i, data.len / (bits / 8)); \
137 ck_assert_int_eq(reader->remaining(reader), data.len % (bits / 8)); \
138 ck_assert(!reader->read_uint##bits##_end(reader, &val)); \
139 reader->destroy(reader); \
140 })
141
142 #define assert_integer_read_end_uneven(data, bits, val) ({ \
143 int i; \
144 data.ptr += bits / 8; \
145 for (i = 0; i <= bits / 8; i++, data.ptr--, data.len++) \
146 { \
147 assert_integer_read_end(data, bits, val); \
148 } \
149 })
150
151 #define assert_basic_read_end(bits, val) ({ \
152 chunk_t data; \
153 data = chunk_empty; \
154 assert_integer_read_end(data, bits, val); \
155 data = chunk_alloca(bits / 8); \
156 memset(data.ptr, 0, data.len); \
157 data.len = 0; \
158 assert_integer_read_end_uneven(data, bits, val); \
159 })
160
161 #define assert_extended_read_end(data, bits, val) ({ \
162 chunk_t extended = chunk_alloca(data.len + bits / 8); \
163 memset(extended.ptr, 0, extended.len); \
164 extended.ptr[bits / 8 - 1] = data.len / (bits / 8); \
165 memcpy(extended.ptr + bits / 8, data.ptr, data.len); \
166 extended.len = data.len; \
167 assert_integer_read_end_uneven(extended, bits, val); \
168 })
169
170 START_TEST(test_read_uint8_end)
171 {
172 chunk_t data = chunk_from_chars(0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00);
173 u_int8_t val;
174
175 assert_integer_read_end(data, 8, val);
176 assert_basic_read_end(8, val);
177 assert_extended_read_end(data, 8, val);
178 }
179 END_TEST
180
181 START_TEST(test_read_uint16_end)
182 {
183 chunk_t data = chunk_from_chars(0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00);
184 u_int16_t val;
185
186 assert_integer_read_end(data, 16, val);
187 assert_basic_read_end(16, val);
188 assert_extended_read_end(data, 16, val);
189 }
190 END_TEST
191
192 START_TEST(test_read_uint24_end)
193 {
194 chunk_t data = chunk_from_chars(0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00);
195 u_int32_t val;
196
197 assert_integer_read_end(data, 24, val);
198 assert_basic_read_end(24, val);
199 assert_extended_read_end(data, 24, val);
200 }
201 END_TEST
202
203 START_TEST(test_read_uint32_end)
204 {
205 chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02,
206 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00);
207 u_int32_t val;
208
209 assert_integer_read_end(data, 32, val);
210 assert_basic_read_end(32, val);
211 assert_extended_read_end(data, 32, val);
212 }
213 END_TEST
214
215 START_TEST(test_read_uint64_end)
216 {
217 chunk_t data = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
221 u_int64_t val;
222
223 assert_integer_read_end(data, 64, val);
224 assert_basic_read_end(64, val);
225 assert_extended_read_end(data, 64, val);
226 }
227 END_TEST
228
229 /*******************************************************************************
230 * read data
231 */
232
233 static inline void assert_reader_after_read(bio_reader_t *reader, chunk_t data)
234 {
235 chunk_t peek;
236
237 ck_assert_int_eq(reader->remaining(reader), data.len);
238 peek = reader->peek(reader);
239 ck_assert_int_eq(reader->remaining(reader), data.len);
240 ck_assert(peek.ptr == data.ptr);
241 data.ptr != NULL ? ck_assert(chunk_equals(peek, data))
242 : ck_assert(peek.ptr == NULL);
243 }
244
245 START_TEST(test_read_data)
246 {
247 chunk_t read, data = chunk_from_chars(0x00, 0x00, 0x00, 0x00);
248 bio_reader_t *reader;
249
250 reader = bio_reader_create(chunk_empty);
251 ck_assert_int_eq(reader->remaining(reader), 0);
252 ck_assert(reader->read_data(reader, 0, &read));
253 ck_assert(!reader->read_data(reader, 1, &read));
254 reader->destroy(reader);
255
256 reader = bio_reader_create(data);
257 ck_assert(reader->read_data(reader, 0, &read));
258 ck_assert_int_eq(read.len, 0);
259 ck_assert(read.ptr == data.ptr);
260 assert_reader_after_read(reader, data);
261
262 ck_assert(reader->read_data(reader, 1, &read));
263 ck_assert_int_eq(read.len, 1);
264 ck_assert(read.ptr == data.ptr);
265 assert_reader_after_read(reader, chunk_skip(data, 1));
266
267 ck_assert(reader->read_data(reader, 2, &read));
268 ck_assert_int_eq(read.len, 2);
269 ck_assert(read.ptr == data.ptr + 1);
270 assert_reader_after_read(reader, chunk_skip(data, 3));
271
272 ck_assert(!reader->read_data(reader, 2, &read));
273 ck_assert(reader->read_data(reader, 1, &read));
274 ck_assert_int_eq(read.len, 1);
275 ck_assert(read.ptr == data.ptr + 3);
276 assert_reader_after_read(reader, chunk_skip(data, 4));
277
278 ck_assert_int_eq(reader->remaining(reader), 0);
279 ck_assert(reader->read_data(reader, 0, &read));
280 ck_assert(!reader->read_data(reader, 1, &read));
281 reader->destroy(reader);
282 }
283 END_TEST
284
285 START_TEST(test_read_data_end)
286 {
287 chunk_t read, data = chunk_from_chars(0x00, 0x00, 0x00, 0x00);
288 bio_reader_t *reader;
289
290 reader = bio_reader_create(chunk_empty);
291 ck_assert_int_eq(reader->remaining(reader), 0);
292 ck_assert(reader->read_data_end(reader, 0, &read));
293 ck_assert(!reader->read_data_end(reader, 1, &read));
294 reader->destroy(reader);
295
296 reader = bio_reader_create(data);
297 ck_assert(reader->read_data_end(reader, 0, &read));
298 ck_assert_int_eq(read.len, 0);
299 ck_assert(read.ptr == data.ptr + data.len);
300 assert_reader_after_read(reader, data);
301
302 ck_assert(reader->read_data_end(reader, 1, &read));
303 ck_assert_int_eq(read.len, 1);
304 data.len--;
305 ck_assert(read.ptr == data.ptr + data.len);
306 assert_reader_after_read(reader, data);
307
308 ck_assert(reader->read_data_end(reader, 2, &read));
309 ck_assert_int_eq(read.len, 2);
310 data.len -= 2;
311 ck_assert(read.ptr == data.ptr + data.len);
312 assert_reader_after_read(reader, data);
313
314 ck_assert(!reader->read_data(reader, 2, &read));
315 ck_assert(reader->read_data(reader, 1, &read));
316 ck_assert_int_eq(read.len, 1);
317 ck_assert(read.ptr == data.ptr);
318 assert_reader_after_read(reader, chunk_empty);
319
320 ck_assert_int_eq(reader->remaining(reader), 0);
321 ck_assert(reader->read_data(reader, 0, &read));
322 ck_assert(!reader->read_data(reader, 1, &read));
323 reader->destroy(reader);
324 }
325 END_TEST
326
327 /*******************************************************************************
328 * read length followed by data
329 */
330
331 #define assert_read_data_len(bits) ({ \
332 bio_reader_t *reader; \
333 chunk_t read, data; \
334 int i, len = bits / 8; \
335 data = chunk_empty; \
336 reader = bio_reader_create(data); \
337 ck_assert(!reader->read_data##bits(reader, &read)); \
338 reader->destroy(reader); \
339 data = chunk_alloca(len + 8); \
340 memset(data.ptr, 0, data.len); \
341 for (i = 0; i <= 8; i++) \
342 { \
343 data.ptr[len - 1] = i; \
344 data.len = len + i; \
345 reader = bio_reader_create(data); \
346 ck_assert(reader->read_data##bits(reader, &read)); \
347 ck_assert_int_eq(reader->remaining(reader), 0); \
348 ck_assert_int_eq(read.len, i); \
349 ck_assert((!read.ptr && !read.len) || (read.ptr == data.ptr + len)); \
350 reader->destroy(reader); \
351 } \
352 data.ptr[len - 1] = i; \
353 reader = bio_reader_create(data); \
354 ck_assert(!reader->read_data##bits(reader, &read)); \
355 reader->destroy(reader); \
356 })
357
358 START_TEST(test_read_data8)
359 {
360 assert_read_data_len(8);
361 }
362 END_TEST
363
364 START_TEST(test_read_data16)
365 {
366 assert_read_data_len(16);
367 }
368 END_TEST
369
370 START_TEST(test_read_data24)
371 {
372 assert_read_data_len(24);
373 }
374 END_TEST
375
376 START_TEST(test_read_data32)
377 {
378 assert_read_data_len(32);
379 }
380 END_TEST
381
382 /*******************************************************************************
383 * test constructors
384 */
385
386 START_TEST(test_create)
387 {
388 chunk_t data = chunk_from_str("foobar");
389 bio_reader_t *reader;
390
391 data = chunk_clone(data);
392 reader = bio_reader_create(data);
393 reader->destroy(reader);
394 chunk_free(&data);
395 }
396 END_TEST
397
398 START_TEST(test_create_own)
399 {
400 chunk_t data = chunk_from_str("foobar");
401 bio_reader_t *reader;
402
403 data = chunk_clone(data);
404 reader = bio_reader_create_own(data);
405 reader->destroy(reader);
406 }
407 END_TEST
408
409 Suite *bio_reader_suite_create()
410 {
411 Suite *s;
412 TCase *tc;
413
414 s = suite_create("bio_reader");
415
416 tc = tcase_create("integer reads");
417 tcase_add_test(tc, test_read_uint8);
418 tcase_add_test(tc, test_read_uint16);
419 tcase_add_test(tc, test_read_uint24);
420 tcase_add_test(tc, test_read_uint32);
421 tcase_add_test(tc, test_read_uint64);
422 suite_add_tcase(s, tc);
423
424 tc = tcase_create("integer reads from end");
425 tcase_add_test(tc, test_read_uint8_end);
426 tcase_add_test(tc, test_read_uint16_end);
427 tcase_add_test(tc, test_read_uint24_end);
428 tcase_add_test(tc, test_read_uint32_end);
429 tcase_add_test(tc, test_read_uint64_end);
430 suite_add_tcase(s, tc);
431
432 tc = tcase_create("data reads and peek");
433 tcase_add_test(tc, test_read_data);
434 tcase_add_test(tc, test_read_data_end);
435 suite_add_tcase(s, tc);
436
437 tc = tcase_create("data length reads");
438 tcase_add_test(tc, test_read_data8);
439 tcase_add_test(tc, test_read_data16);
440 tcase_add_test(tc, test_read_data24);
441 tcase_add_test(tc, test_read_data32);
442 suite_add_tcase(s, tc);
443
444 tc = tcase_create("constructors");
445 tcase_add_test(tc, test_create);
446 tcase_add_test(tc, test_create_own);
447 suite_add_tcase(s, tc);
448
449 return s;
450 }