The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
dbuff_tests.c
Go to the documentation of this file.
1#include "acutest.h"
2#include"acutest_helpers.h"
3#include <float.h>
4
5#include <freeradius-devel/util/dbuff.h>
6
7/*
8 * Type for a function with the internals of a test of fd flavored dbuffs.
9 */
10typedef void (*fr_dbuff_fd_test_body)(fr_dbuff_t *dbuff, uint8_t const data[]);
11
12static void test_dbuff_init(void)
13{
14 uint8_t const in[] = { 0x01, 0x02, 0x03, 0x04 };
15 fr_dbuff_t dbuff;
16
17 TEST_CASE("Parse init with size");
18 fr_dbuff_init(&dbuff, in, sizeof(in));
19
20 TEST_CHECK(dbuff.start == in);
21 TEST_CHECK(dbuff.p == in);
22 TEST_CHECK(dbuff.end == in + sizeof(in));
23
24 TEST_CASE("Parse init with end");
25 fr_dbuff_init(&dbuff, in, in + sizeof(in));
26
27 TEST_CHECK(dbuff.start == in);
28 TEST_CHECK(dbuff.p == in);
29 TEST_CHECK(dbuff.end == in + sizeof(in));
30
31 TEST_CASE("Parse init with const end");
32 fr_dbuff_init(&dbuff, in, (uint8_t const *)(in + sizeof(in)));
33
34 TEST_CHECK(dbuff.start == in);
35 TEST_CHECK(dbuff.p == in);
36 TEST_CHECK(dbuff.end == in + sizeof(in));
37}
38
40{ uint8_t const in[] = { 0x01, 0x02, 0x03, 0x04 };
41 fr_dbuff_t dbuff;
42
43 TEST_CASE("Confirm init returns parentless dbuff");
44 fr_dbuff_init(&dbuff, in, sizeof(in));
45
46 TEST_CHECK(dbuff.parent == NULL);
47}
48
49static void test_dbuff_max(void)
50{
51 uint8_t const in[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
52 fr_dbuff_t dbuff;
53 fr_dbuff_t max_dbuff;
54
55 TEST_CASE("Confirm max constrains available space");
56 fr_dbuff_init(&dbuff, in, sizeof(in));
57
58 max_dbuff = FR_DBUFF_MAX_BIND_CURRENT(&dbuff, 4);
59 TEST_CHECK(fr_dbuff_remaining(&max_dbuff) == 4);
60
61 max_dbuff = FR_DBUFF_MAX_BIND_CURRENT(&dbuff, 2 * sizeof(in));
62 TEST_CHECK(fr_dbuff_remaining(&max_dbuff) == sizeof(in));
63}
64
65
66/** Test the various dbuff_net_encode() functions and macros
67 *
68 * @note Passing constants to fr_dbuff_in() as it is written results in
69 * warnings about narrowing casts on the constants--but those casts are in
70 * the underlying inlined fr_nbo_from*() functions. They have to be there;
71 * that's how those functions work. (The tests worked despite the warnings.)
72 * Using variables avoids the warnings, at least with the compile options
73 * the build system uses by default.
74 */
75static void test_dbuff_net_encode(void)
76{
77 uint8_t buff[sizeof(uint64_t)];
78 fr_dbuff_t dbuff;
79 fr_dbuff_marker_t marker;
80 uint16_t u16val = 0x1234;
81 uint16_t u16val2 = 0xcdef;
82 uint32_t u32val = 0x12345678;
83 uint64_t u64val = 0x123456789abcdef0;
84 int16_t i16val = 0x1234;
85 int32_t i32val = 0xd34d;
86 int64_t i64val = 0x123456789abcdef0;
87 float float_in = 1.0f + FLT_EPSILON;
88 float float_out = 0;
89 double double_in = 1.0 + DBL_EPSILON;
90 double double_out = 0;
91 uint64_t u64v_vals[] = {
92 0, 0x12, 0x3412, 0x563412, 0x78563412, 0x9a78563412,
93 0xbc9a78563412, 0xdebc9a78563412, 0xf0debc9a78563412
94 };
95
96 TEST_CASE("Generate wire format unsigned 16-bit value");
97 memset(buff, 0, sizeof(buff));
98 fr_dbuff_init(&dbuff, buff, sizeof(buff));
99 fr_dbuff_marker(&marker, &dbuff);
100
101 TEST_CHECK(fr_dbuff_in(&dbuff, u16val) == sizeof(uint16_t));
102 TEST_CHECK(*((uint16_t *)buff) == htons(u16val));
103
104 TEST_CASE("Generate wire format unsigned 16-bit value using marker");
105 fr_dbuff_set_to_start(&dbuff);
106 TEST_CHECK(fr_dbuff_in(&marker, u16val2) == sizeof(uint16_t));
107 TEST_CHECK(*((uint16_t *)buff) == htons(u16val2));
108 TEST_CHECK(fr_dbuff_used(&marker) == sizeof(uint16_t));
109 TEST_CHECK(fr_dbuff_used(&dbuff) == 0);
110
111 TEST_CASE("Generate wire format unsigned 32-bit value");
112 memset(buff, 0, sizeof(buff));
113 fr_dbuff_init(&dbuff, buff, sizeof(buff));
114
115 TEST_CHECK(fr_dbuff_in(&dbuff, u32val) == sizeof(uint32_t));
116 TEST_CHECK(*((uint32_t *)buff) == htonl(u32val));
117
118 TEST_CASE("Generate wire format unsigned 64-bit value");
119 memset(buff, 0, sizeof(buff));
120 fr_dbuff_init(&dbuff, buff, sizeof(buff));
121
122 TEST_CHECK(fr_dbuff_in(&dbuff, u64val) == sizeof(uint64_t));
123 TEST_CHECK(*((uint64_t *)buff) == htonll(u64val));
124
125 TEST_CASE("Generate wire format signed 16-bit value");
126 memset(buff, 0, sizeof(buff));
127 fr_dbuff_init(&dbuff, buff, sizeof(buff));
128
129 TEST_CHECK(fr_dbuff_in(&dbuff, i16val) == sizeof(int16_t));
130 TEST_CHECK(*((uint16_t *)buff) == htons((uint16_t) i16val));
131
132 TEST_CASE("Generate wire format signed 32-bit value");
133 memset(buff, 0, sizeof(buff));
134 fr_dbuff_init(&dbuff, buff, sizeof(buff));
135
136 TEST_CHECK(fr_dbuff_in(&dbuff, i32val) == sizeof(int32_t));
137 TEST_CHECK(*((uint32_t *)buff) == htonl((uint32_t) i32val));
138
139 TEST_CASE("Generate wire format signed 64-bit value");
140 memset(buff, 0, sizeof(buff));
141 fr_dbuff_init(&dbuff, buff, sizeof(buff));
142
143 TEST_CHECK(fr_dbuff_in(&dbuff, i64val) == sizeof(int64_t));
144 TEST_CHECK(*((uint64_t *)buff) == htonll((uint64_t) i64val));
145
146 TEST_CASE("Generate wire format variable-width");
147 for (size_t i = 0; i < (sizeof(u64v_vals) / sizeof(uint64_t)); i++) {
148 uint64_t val = u64v_vals[i];
149 int num_bytes;
150
151 fr_dbuff_set_to_start(&dbuff);
152 for (num_bytes = 1; (val & ~((uint64_t) 0xff)) != 0; num_bytes++) val >>= 8;
153 TEST_CHECK(fr_dbuff_in_uint64v(&dbuff, u64v_vals[i]) == num_bytes);
154 val = u64v_vals[i];
155 fr_dbuff_set_to_start(&dbuff);
156 for (int j = num_bytes; --j >= 0; ) {
157 uint8_t byte = 0;
158
159 TEST_CHECK(fr_dbuff_out(&byte, &dbuff) == 1);
160 TEST_CHECK(byte == (uint8_t) (val >> (8 * j)));
161 }
162 }
163
164 TEST_CASE("Generate wire-format float");
165 memset(buff, 0, sizeof(buff));
166 fr_dbuff_init(&dbuff, buff, sizeof(buff));
167 TEST_CHECK(fr_dbuff_in(&dbuff, float_in) == 4);
168 fr_dbuff_set_to_start(&dbuff);
169 TEST_CHECK(fr_dbuff_out(&float_out, &dbuff) == 4);
170 TEST_CHECK(memcmp(&float_out, &float_in, sizeof(float)) == 0);
171
172 TEST_CASE("Generate wire-format double");
173 memset(buff, 0, sizeof(buff));
174 fr_dbuff_init(&dbuff, buff, sizeof(buff));
175 TEST_CHECK(fr_dbuff_in(&dbuff, double_in) == 8);
176 fr_dbuff_set_to_start(&dbuff);
177 TEST_CHECK(fr_dbuff_out(&double_out, &dbuff) == 8);
178 TEST_CHECK(memcmp(&double_out, &double_in, sizeof(double)) == 0);
179
180 TEST_CASE("Refuse to write to too-small space");
181 fr_dbuff_init(&dbuff, buff, sizeof(uint32_t));
182
183 TEST_CHECK(fr_dbuff_in(&dbuff, u64val) == -(ssize_t)(sizeof(uint64_t) - sizeof(uint32_t)));
184
185 TEST_CASE("Input bytes using dbuff current position");
186 memset(buff, 0, sizeof(buff));
187 fr_dbuff_init(&dbuff, buff, sizeof(buff));
188 fr_dbuff_marker(&marker, &dbuff);
189 TEST_CHECK(fr_dbuff_in_bytes(&dbuff, 0xf0, 0xed, 0xcb) == 3);
190 TEST_CHECK(buff[0] == 0xf0);
191 TEST_CHECK(buff[1] == 0xed);
192 TEST_CHECK(buff[2] == 0xcb);
193 TEST_CHECK(fr_dbuff_used(&dbuff) == 3);
194 TEST_CASE("Input bytes using marker");
195 TEST_CHECK(fr_dbuff_in_bytes(&marker, 0x01, 0x23) == 2);
196 TEST_CHECK(buff[0] == 0x01);
197 TEST_CHECK(buff[1] == 0x23);
198 TEST_CHECK(fr_dbuff_used(&marker) == 2);
199}
200
201static void test_dbuff_no_advance(void)
202{
203 uint8_t in[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
204 fr_dbuff_t dbuff;
205 fr_dbuff_t no_advance_dbuff;
206 size_t init_remaining;
207
208 TEST_CASE("Confirm no-advance dbuff operations don't affect ancestors' position");
209 fr_dbuff_init(&dbuff, in, sizeof(in));
210
211 no_advance_dbuff = FR_DBUFF(&dbuff);
212 init_remaining = fr_dbuff_remaining(&dbuff);
213 TEST_CHECK(fr_dbuff_in_bytes(&no_advance_dbuff, 0x11, 0x12, 0x13) == 3);
214 TEST_CHECK(init_remaining == fr_dbuff_remaining(&dbuff));
215 fr_dbuff_advance(&no_advance_dbuff, 2);
216 TEST_CHECK(init_remaining == fr_dbuff_remaining(&dbuff));
217 fr_dbuff_set_to_end(&no_advance_dbuff);
218 TEST_CHECK(init_remaining == fr_dbuff_remaining(&dbuff));
219}
220
221static void test_dbuff_move(void)
222{
223 uint8_t buff1[26], buff2[26], buff3[10];
224 fr_dbuff_t dbuff1, dbuff2, dbuff3;
225 fr_dbuff_marker_t marker1, marker2;
226
227 memcpy(buff1, "abcdefghijklmnopqrstuvwxyz", sizeof(buff1));
228 memcpy(buff2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", sizeof(buff2));
229 memcpy(buff3, "0123456789", sizeof(buff3));
230 fr_dbuff_init(&dbuff1, buff1, sizeof(buff1));
231 fr_dbuff_init(&dbuff2, buff2, sizeof(buff2));
232 fr_dbuff_init(&dbuff3, buff3, sizeof(buff3));
233 fr_dbuff_marker(&marker1, &dbuff1);
234 fr_dbuff_marker(&marker2, &dbuff2);
235
236 TEST_CASE("move dbuff to dbuff");
237 TEST_CHECK_LEN(fr_dbuff_move(&dbuff1, &dbuff2, 13), 13);
238 TEST_CHECK_LEN(fr_dbuff_used(&dbuff1), 13);
239 TEST_CHECK_LEN(fr_dbuff_used(&dbuff2), 13);
240 TEST_CHECK(memcmp(dbuff1.start, "ABCDEFGHIJKLMnopqrstuvwxyz", 26) == 0);
241
242 TEST_CASE("move dbuff to marker");
243 TEST_CHECK_SLEN(fr_dbuff_advance(&marker2, 4), 4);
244 TEST_CHECK_LEN(fr_dbuff_move(&marker2, &dbuff3, 10), 10);
245 TEST_CHECK_LEN(fr_dbuff_used(&marker2), 14);
246 TEST_CHECK(memcmp(dbuff2.start, "ABCD0123456789OPQRSTUVWXYZ", 26) == 0);
247
248 TEST_CASE("move marker to dbuff");
249 TEST_CHECK_SLEN(fr_dbuff_advance(&marker1, 7), 7);
250 TEST_CHECK_LEN(fr_dbuff_move(&dbuff1, &marker1, 6), 6);
251 TEST_CHECK_LEN(fr_dbuff_used(&dbuff1), 19);
252 TEST_CHECK_LEN(fr_dbuff_used(&marker1), 13);
253 TEST_CHECK(memcmp(dbuff1.start, "ABCDEFGHIJKLMHIJKLMtuvwxyz", 26) == 0);
254
255 TEST_CASE("move marker to marker");
256 TEST_CHECK_LEN(fr_dbuff_move(&marker2, &marker1, 8), 8);
257 TEST_CHECK_LEN(fr_dbuff_used(&marker1), 21);
258 TEST_CHECK_LEN(fr_dbuff_used(&marker2), 22);
259 TEST_CHECK(memcmp(dbuff2.start, "ABCD0123456789HIJKLMtuWXYZ", 26) == 0);
260}
261
262/** Test extensible dbuffs
263 *
264 */
265
267{
268 fr_dbuff_t dbuff1, dbuff2;
269 fr_dbuff_uctx_talloc_t tctx1, tctx2;
270 fr_dbuff_marker_t marker1;
271 uint8_t const value[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
272
273 TEST_CASE("Initial allocation");
274 TEST_CHECK(fr_dbuff_init_talloc(NULL, &dbuff1, &tctx1, 4, 14) == &dbuff1);
275 TEST_CHECK(fr_dbuff_used(&dbuff1) == 0);
276 TEST_CHECK(fr_dbuff_remaining(&dbuff1) == 4);
277 fr_dbuff_marker(&marker1, &dbuff1);
278
279 TEST_CASE("Extension");
280 TEST_CHECK(fr_dbuff_in(&dbuff1, (uint64_t) 0x123456789abcdef0) == sizeof(uint64_t));
281 TEST_CASE("Markers track extended buffer");
282 TEST_CHECK(marker1.p == dbuff1.start);
283 TEST_CASE("Already-written content stays with the buffer");
284 TEST_CHECK(memcmp(fr_dbuff_current(&marker1), value, sizeof(value)) == 0);
285 TEST_CASE("Refuse to extend past specified maximum");
286 TEST_CHECK(fr_dbuff_in(&dbuff1, (uint64_t) 0x123456789abcdef0) == -2);
287 TEST_CASE("Extend move destination if possible and input length demands");
288 TEST_CHECK(fr_dbuff_init_talloc(NULL, &dbuff2, &tctx2, 4, 14) == &dbuff2);
289 fr_dbuff_set_to_start(&dbuff1);
290 TEST_CHECK(fr_dbuff_move(&dbuff2, &dbuff1, sizeof(value)) == sizeof(value));
291 TEST_CHECK(fr_dbuff_used(&dbuff2) == sizeof(value));
292 /*
293 * @todo: the analogous test for extensible source.
294 */
295
296 talloc_free(dbuff1.buff);
297 talloc_free(dbuff2.buff);
298}
299
301{
302 fr_dbuff_t dbuff1, dbuff2;
303 fr_dbuff_uctx_talloc_t tctx;
304
305 TEST_CASE("Initial allocation");
306 TEST_CHECK(fr_dbuff_init_talloc(NULL, &dbuff1, &tctx, 0, 32) == &dbuff1);
307 TEST_CHECK(fr_dbuff_used(&dbuff1) == 0);
308 TEST_CHECK(fr_dbuff_remaining(&dbuff1) == 0);
309
310 dbuff2 = FR_DBUFF(&dbuff1);
311 TEST_CASE("Check that dbuff2 inherits extend fields");
312 TEST_CHECK(dbuff2.extend == dbuff1.extend);
313 TEST_CHECK(dbuff2.uctx == dbuff1.uctx);
314 TEST_CHECK(fr_dbuff_used(&dbuff2) == 0);
315 TEST_CHECK(fr_dbuff_remaining(&dbuff2) == 0);
316
317 dbuff2 = FR_DBUFF_MAX_BIND_CURRENT(&dbuff1, 8);
318 TEST_CASE("Check that FR_DBUFF_MAX_BIND_CURRENT() is not extensible");
319 TEST_CHECK(dbuff2.extend == NULL);
320 TEST_CHECK(dbuff2.uctx == NULL);
321 TEST_CHECK(fr_dbuff_used(&dbuff2) == 0);
322 TEST_CHECK(fr_dbuff_remaining(&dbuff2) == 0);
323 TEST_CHECK(fr_dbuff_in(&dbuff2, (uint64_t) 0x123456789abcdef0) == -8);
324
325 talloc_free(dbuff1.buff);
326}
327
328/*
329 * test_dbuff_fd_shell() puts setup and teardown of a fd flavored dbuff in one place
330 * so jscpd won't complain about copy/paste.
331 */
332static void test_dbuff_fd_shell(fr_dbuff_fd_test_body body, uint8_t const data[], size_t datasize,
333 uint8_t buff[], size_t buffsize, size_t max)
334{
335 int fd[2];
336 fr_dbuff_t dbuff;
337 fr_dbuff_uctx_fd_t fctx;
338
339 TEST_CASE("Initial allocation");
340 TEST_CHECK(pipe(fd) == 0);
341 TEST_CHECK(write(fd[1], data, datasize) == (ssize_t) datasize);
342 close(fd[1]);
343 TEST_CHECK(fr_dbuff_init_fd(&dbuff, &fctx, buff, buffsize, fd[0], max) == &dbuff);
344
345 body(&dbuff, data);
346
347 close(fd[0]);
348}
349
350static void fd_body(fr_dbuff_t *dbuff, uint8_t const data[])
351{
352 uint8_t output[8] = { 0x00 };
353
354 TEST_CASE("Initial extend");
355 TEST_CHECK(fr_dbuff_out_memcpy(output, dbuff, 1) == 1);
356 TEST_CHECK(memcmp(output, data, 1) == 0);
357 TEST_CHECK(fr_dbuff_out_memcpy(output, dbuff, 2) == 2);
358 TEST_CHECK(memcmp(output, &data[1], 2) == 0);
359 TEST_CASE("Leftover byte plus data from next extend");
360 TEST_CHECK(fr_dbuff_out_memcpy(output, dbuff, 4) == 4);
361 TEST_CHECK(memcmp(output, &data[3], 4) == 0);
362 TEST_CASE("Multiple extends");
363 TEST_CHECK(fr_dbuff_out_memcpy(output, dbuff, 8) == 8);
364 TEST_CHECK(memcmp(output, &data[7], 8) == 0);
365 TEST_CASE("EOF");
366 TEST_CHECK(fr_dbuff_out_memcpy(output, dbuff, 4) == -3);
367}
368
369static void test_dbuff_fd(void)
370{
371 uint8_t const data[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
372 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
373 uint8_t buff[4];
374
375 test_dbuff_fd_shell(fd_body, data, sizeof(data), buff, sizeof(buff), 24);
376}
377
378
379static void max_body(fr_dbuff_t *dbuff, uint8_t const data[])
380{
381 uint8_t output[8];
382
383 TEST_CASE("Initial extend");
384 TEST_CHECK(fr_dbuff_out_memcpy(output, dbuff, 2) == 2);
385 TEST_CHECK(memcmp(output, data, 2) == 0);
386 TEST_CHECK(fr_dbuff_out_memcpy(output, dbuff, 1) == 1);
387 TEST_CHECK(memcmp(output, &data[2], 1) == 0);
388 TEST_CHECK(fr_dbuff_out_memcpy(output, dbuff, 4) == 4);
389 TEST_CHECK(memcmp(output, &data[3], 4) == 0);
390 TEST_CASE("Confirm that max precludes another shift/extend");
391 TEST_CHECK(fr_dbuff_out_memcpy(output, dbuff, 8) == -7);
392}
393
394static void test_dbuff_fd_max(void)
395{
396 uint8_t const data[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
397 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
398 uint8_t buff[4];
399
400
401 test_dbuff_fd_shell(max_body, data, sizeof(data), buff, sizeof(buff), 8);
402}
403
404/** Test functions that read from dbuffs.
405 *
406 */
407static void test_dbuff_out(void)
408{
409 uint8_t const buff1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
410 uint8_t buff2[8];
411 uint8_t buff3[8];
412 fr_dbuff_t dbuff1;
413 fr_dbuff_t dbuff2;
414 fr_dbuff_marker_t marker1;
415 uint8_t u8val = 0;
416 uint16_t u16val = 0;
417 uint32_t u32val = 0;
418 uint64_t u64val = 0;
419 uint64_t u64val2 = 0;
420 int8_t i8val = 0;
421 int16_t i16val = 0;
422 int32_t i32val = 0;
423 int64_t i64val = 0;
424 float fval1 = 1.5, fval2 = 0;
425 double dval1 = 2048.0625, dval2 = 0;
426
427 fr_dbuff_init(&dbuff1, buff1, sizeof(buff1));
428 fr_dbuff_init(&dbuff2, buff2, sizeof(buff2));
429
430 TEST_CASE("Check dbuff reads of unsigned integers");
431 TEST_CHECK(fr_dbuff_out(&u8val, &dbuff1) == 1);
432 TEST_CHECK(u8val == 0x01);
433 TEST_CHECK(fr_dbuff_out(&u16val, &dbuff1) == 2);
434 TEST_CHECK(u16val == 0x2345);
435 TEST_CHECK(fr_dbuff_out(&u32val, &dbuff1) == 4);
436 TEST_CHECK(u32val == 0x6789abcd);
437 fr_dbuff_set_to_start(&dbuff1);
438 TEST_CHECK(fr_dbuff_out(&u64val, &dbuff1) == 8);
439 TEST_CHECK(u64val == 0x0123456789abcdef);
440
441 TEST_CASE("Don't walk off the end of the buffer");
442 TEST_CHECK(fr_dbuff_out(&u32val, &dbuff1) == -4);
443
444 TEST_CASE("Check dbuff reads using markers");
445 fr_dbuff_set_to_start(&dbuff1);
446 fr_dbuff_marker(&marker1, &dbuff1);
447 TEST_CHECK(fr_dbuff_out(&u64val, &marker1) == 8);
448 TEST_CHECK(fr_dbuff_out(&u64val2, &dbuff1) == 8);
449 TEST_CHECK(u64val == u64val2);
450 TEST_CHECK(fr_dbuff_current(&dbuff1) == fr_dbuff_current(&marker1));
451
452 TEST_CASE("Check dbuff reads of signed integers");
453 fr_dbuff_set_to_start(&dbuff1);
454 TEST_CHECK(fr_dbuff_out(&i8val, &dbuff1) == 1);
455 TEST_CHECK(i8val == 0x01);
456 TEST_CHECK(fr_dbuff_out(&i16val, &dbuff1) == 2);
457 TEST_CHECK(i16val == 0x2345);
458 TEST_CHECK(fr_dbuff_out(&i32val, &dbuff1) == 4);
459 TEST_CHECK(i32val == 0x6789abcd);
460 fr_dbuff_set_to_start(&dbuff1);
461 TEST_CHECK(fr_dbuff_out(&i64val, &dbuff1) == 8);
462 TEST_CHECK(i64val == 0x0123456789abcdef);
463
464 TEST_CASE("Check dbuff reads of floating point values");
465 TEST_CHECK(fr_dbuff_in(&dbuff2, *(uint32_t *)&fval1) == 4);
466 fr_dbuff_set_to_start(&dbuff2);
467 TEST_CHECK(fr_dbuff_out(&fval2, &dbuff2) == 4);
468 TEST_CHECK(memcmp(&fval1, &fval2, sizeof(fval1)) == 0);
469 fr_dbuff_set_to_start(&dbuff2);
470 TEST_CHECK(fr_dbuff_in(&dbuff2, *(uint64_t *)&dval1) == 8);
471 fr_dbuff_set_to_start(&dbuff2);
472 TEST_CHECK(fr_dbuff_out(&dval2, &dbuff2) == 8);
473 TEST_CHECK(memcmp(&dval1, &dval2, sizeof(dval1)) == 0);
474
475 TEST_CASE("Check variable length uint64_t read");
476 fr_dbuff_set_to_start(&dbuff1);
477 TEST_CHECK(fr_dbuff_out_uint64v(&u64val, &dbuff1, 2) == 2);
478 TEST_CHECK(u64val == 0x0123);
479 TEST_CHECK(fr_dbuff_out_uint64v(&u64val, &dbuff1, 4) == 4);
480 TEST_CHECK(u64val == 0x456789ab);
481 fr_dbuff_set_to_start(&dbuff1);
482 TEST_CHECK(fr_dbuff_out_uint64v(&u64val, &dbuff1, 8) == 8);
483 TEST_CHECK(u64val == 0x0123456789abcdef);
484
485 TEST_CASE("fr_dbuff_out_memcpy");
486 fr_dbuff_set_to_start(&dbuff1);
487 fr_dbuff_set_to_start(&dbuff2);
488 fr_dbuff_marker(&marker1, &dbuff1);
489 memset(buff3, 0, sizeof(buff3));
490 TEST_CHECK(fr_dbuff_out_memcpy(buff3, &dbuff1, 7) == 7);
491 TEST_CHECK(memcmp(buff3, fr_dbuff_start(&dbuff1), 7) == 0 && buff3[7] == 0);
492 TEST_CHECK(fr_dbuff_current(&dbuff1) - fr_dbuff_current(&marker1) == 7);
493 fr_dbuff_set_to_start(&dbuff1);
494 TEST_CHECK(fr_dbuff_out_memcpy(&dbuff2, &dbuff1, 4) == 4);
495 fr_dbuff_set_to_start(&dbuff1);
496 fr_dbuff_advance(&dbuff1, 3);
497 fr_dbuff_advance(&dbuff2, 2);
498 TEST_CHECK(fr_dbuff_out_memcpy(&dbuff2, &dbuff1, 4) == 4);
499 TEST_CHECK(memcmp(fr_dbuff_start(&dbuff2), fr_dbuff_start(&dbuff1), 2) == 0 &&
500 memcmp(fr_dbuff_start(&dbuff2) + 2, fr_dbuff_start(&dbuff1) + 3, 4) == 0);
501 memset(buff3, 0, sizeof(buff3));
502 fr_dbuff_set_to_start(&marker1);
503 TEST_CHECK(fr_dbuff_out_memcpy(buff3, &marker1, 4) == 4);
504 TEST_CHECK(memcmp(buff3, buff1, 4) == 0);
505 TEST_CHECK(fr_dbuff_current(&marker1) - fr_dbuff_start(&dbuff1) == 4);
506}
507
509 /*
510 * Basic tests
511 */
512 { "fr_dbuff_init", test_dbuff_init },
513 { "fr_dbuff_init_no_parent", test_dbuff_init_no_parent },
514 { "fr_dbuff_max", test_dbuff_max },
515 { "fr_dbuff_in", test_dbuff_net_encode },
516 { "fr_dbuff_no_advance", test_dbuff_no_advance },
517 { "fr_dbuff_move", test_dbuff_move },
518 { "fr_dbuff_talloc_extend", test_dbuff_talloc_extend },
519 { "fr_dbuff_talloc_extend_multi_level", test_dbuff_talloc_extend_multi_level },
520 { "fr_dbuff_fd", test_dbuff_fd },
521 { "fr_dbuff_fd_max", test_dbuff_fd_max },
522 { "fr_dbuff_out", test_dbuff_out },
523
524
526};
527
#define TEST_CHECK(cond)
Definition acutest.h:87
#define TEST_CASE(name)
Definition acutest.h:186
#define TEST_TERMINATOR
Definition acutest.h:64
#define TEST_CHECK_SLEN(_got, _exp)
#define TEST_CHECK_LEN(_got, _exp)
#define fr_dbuff_advance(_dbuff_or_marker, _len)
Advance 'current' position in dbuff or marker by _len bytes.
Definition dbuff.h:1081
#define fr_dbuff_used(_dbuff_or_marker)
Return the number of bytes remaining between the start of the dbuff or marker and the current positio...
Definition dbuff.h:775
static fr_dbuff_t * fr_dbuff_init_fd(fr_dbuff_t *dbuff, fr_dbuff_uctx_fd_t *fctx, uint8_t *buff, size_t len, int fd, size_t max)
Initialise a special dbuff which automatically reads in more data as the buffer is exhausted.
Definition dbuff.h:493
struct fr_dbuff_marker_s fr_dbuff_marker_t
A position marker associated with a dbuff.
Definition dbuff.h:81
#define fr_dbuff_out_uint64v(_num, _dbuff_or_marker, _len)
Read bytes from a dbuff or marker and interpret them as a network order unsigned integer.
Definition dbuff.h:1860
#define fr_dbuff_current(_dbuff_or_marker)
Return the 'current' position of a dbuff or marker.
Definition dbuff.h:919
#define fr_dbuff_init(_out, _start, _len_or_end)
Initialise an dbuff for encoding or decoding.
Definition dbuff.h:362
#define fr_dbuff_start(_dbuff_or_marker)
Return the 'start' position of a dbuff or marker.
Definition dbuff.h:906
#define fr_dbuff_set_to_start(_dbuff_or_marker)
Reset the 'current' position of the dbuff or marker to the 'start' of the buffer.
Definition dbuff.h:1164
#define fr_dbuff_out_memcpy(_out, _dbuff_or_marker, _outlen)
Copy exactly _outlen bytes from the dbuff.
Definition dbuff.h:1741
#define fr_dbuff_remaining(_dbuff_or_marker)
Return the number of bytes remaining between the dbuff or marker and the end of the buffer.
Definition dbuff.h:751
#define fr_dbuff_in_bytes(_dbuff_or_marker,...)
Copy a byte sequence into a dbuff or marker.
Definition dbuff.h:1474
static uint8_t * fr_dbuff_marker(fr_dbuff_marker_t *m, fr_dbuff_t *dbuff)
Initialises a new marker pointing to the 'current' position of the dbuff.
Definition dbuff.h:1201
#define fr_dbuff_in_uint64v(_dbuff_or_marker, _num)
Copy an integer value into a dbuff or marker using our internal variable length encoding.
Definition dbuff.h:1621
#define fr_dbuff_in(_dbuff_or_marker, _in)
Copy data from a fixed sized C type into a dbuff or marker.
Definition dbuff.h:1576
#define fr_dbuff_set_to_end(_dbuff_or_marker)
Reset the 'current' position of the dbuff or marker to the 'end' of the buffer.
Definition dbuff.h:1170
#define FR_DBUFF(_dbuff_or_marker)
Create a new dbuff pointing to the same underlying buffer.
Definition dbuff.h:230
#define fr_dbuff_move(_out, _in, _len)
Copy in as many bytes as possible from one dbuff or marker to another.
Definition dbuff.h:1665
#define FR_DBUFF_MAX_BIND_CURRENT(_dbuff_or_marker, _max)
Limit the maximum number of bytes available in the dbuff when passing it to another function.
Definition dbuff.h:326
static fr_dbuff_t * fr_dbuff_init_talloc(TALLOC_CTX *ctx, fr_dbuff_t *dbuff, fr_dbuff_uctx_talloc_t *tctx, size_t init, size_t max)
Initialise a special dbuff which automatically extends as additional data is written.
Definition dbuff.h:419
#define fr_dbuff_out(_out, _dbuff_or_marker)
Copy data from a dbuff or marker to a fixed sized C type.
Definition dbuff.h:1808
TEST_LIST
static void test_dbuff_init_no_parent(void)
Definition dbuff_tests.c:39
static void fd_body(fr_dbuff_t *dbuff, uint8_t const data[])
static void test_dbuff_fd_shell(fr_dbuff_fd_test_body body, uint8_t const data[], size_t datasize, uint8_t buff[], size_t buffsize, size_t max)
void(* fr_dbuff_fd_test_body)(fr_dbuff_t *dbuff, uint8_t const data[])
Definition dbuff_tests.c:10
static void test_dbuff_talloc_extend(void)
Test extensible dbuffs.
static void test_dbuff_out(void)
Test functions that read from dbuffs.
static void test_dbuff_max(void)
Definition dbuff_tests.c:49
static void test_dbuff_talloc_extend_multi_level(void)
static void test_dbuff_init(void)
Definition dbuff_tests.c:12
static void max_body(fr_dbuff_t *dbuff, uint8_t const data[])
static void test_dbuff_no_advance(void)
static void test_dbuff_net_encode(void)
Test the various dbuff_net_encode() functions and macros.
Definition dbuff_tests.c:75
static void test_dbuff_move(void)
static void test_dbuff_fd(void)
static void test_dbuff_fd_max(void)
static fr_slen_t in
Definition dict.h:882
Test enumeration values.
Definition dict_test.h:92
talloc_free(hp)
unsigned short uint16_t
uint8_t * p
unsigned int uint32_t
long int ssize_t
unsigned char uint8_t
static char buff[sizeof("18446744073709551615")+3]
Definition size_tests.c:37
static fr_slen_t data
Definition value.h:1340