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