1 #include <freeradius-devel/util/acutest.h>
2 #include <freeradius-devel/util/acutest_helpers.h>
16 uint8_t const in[] = { 0x01, 0x02, 0x03, 0x04 };
42 {
uint8_t const in[] = { 0x01, 0x02, 0x03, 0x04 };
45 TEST_CASE(
"Confirm init returns parentless dbuff");
53 uint8_t const in[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
57 TEST_CASE(
"Confirm max constrains available space");
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;
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
98 TEST_CASE(
"Generate wire format unsigned 16-bit value");
106 TEST_CASE(
"Generate wire format unsigned 16-bit value using marker");
113 TEST_CASE(
"Generate wire format unsigned 32-bit value");
120 TEST_CASE(
"Generate wire format unsigned 64-bit value");
127 TEST_CASE(
"Generate wire format signed 16-bit value");
134 TEST_CASE(
"Generate wire format signed 32-bit value");
141 TEST_CASE(
"Generate wire format signed 64-bit value");
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];
154 for (num_bytes = 1; (val & ~((uint64_t) 0xff)) != 0; num_bytes++) val >>= 8;
158 for (
int j = num_bytes; --j >= 0; ) {
172 TEST_CHECK(memcmp(&float_out, &float_in,
sizeof(
float)) == 0);
174 TEST_CASE(
"Generate wire-format double");
180 TEST_CHECK(memcmp(&double_out, &double_in,
sizeof(
double)) == 0);
182 TEST_CASE(
"Refuse to write to too-small space");
187 TEST_CASE(
"Input bytes using dbuff current position");
205 uint8_t in[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
208 size_t init_remaining;
210 TEST_CASE(
"Confirm no-advance dbuff operations don't affect ancestors' position");
213 no_advance_dbuff =
FR_DBUFF(&dbuff);
225 uint8_t buff1[26], buff2[26], buff3[10];
229 memcpy(buff1,
"abcdefghijklmnopqrstuvwxyz",
sizeof(buff1));
230 memcpy(buff2,
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
sizeof(buff2));
231 memcpy(buff3,
"0123456789",
sizeof(buff3));
242 TEST_CHECK(memcmp(dbuff1.start,
"ABCDEFGHIJKLMnopqrstuvwxyz", 26) == 0);
248 TEST_CHECK(memcmp(dbuff2.start,
"ABCD0123456789OPQRSTUVWXYZ", 26) == 0);
255 TEST_CHECK(memcmp(dbuff1.start,
"ABCDEFGHIJKLMHIJKLMtuvwxyz", 26) == 0);
261 TEST_CHECK(memcmp(dbuff2.start,
"ABCD0123456789HIJKLMtuWXYZ", 26) == 0);
271 fr_dbuff_uctx_talloc_t tctx1, tctx2;
273 uint8_t const value[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
283 TEST_CASE(
"Markers track extended buffer");
285 TEST_CASE(
"Already-written content stays with the buffer");
287 TEST_CASE(
"Refuse to extend past specified maximum");
289 TEST_CASE(
"Extend move destination if possible and input length demands");
305 fr_dbuff_uctx_talloc_t tctx;
313 TEST_CASE(
"Check that dbuff2 inherits extend fields");
320 TEST_CASE(
"Check that FR_DBUFF_MAX_BIND_CURRENT() is not extensible");
339 fr_dbuff_uctx_fd_t fctx;
361 TEST_CASE(
"Leftover byte plus data from next extend");
373 uint8_t const data[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
374 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
392 TEST_CASE(
"Confirm that max precludes another shift/extend");
398 uint8_t const data[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
399 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
411 uint8_t const buff1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
421 uint64_t u64val2 = 0;
426 float fval1 = 1.5, fval2 = 0;
427 double dval1 = 2048.0625, dval2 = 0;
432 TEST_CASE(
"Check dbuff reads of unsigned integers");
443 TEST_CASE(
"Don't walk off the end of the buffer");
446 TEST_CASE(
"Check dbuff reads using markers");
454 TEST_CASE(
"Check dbuff reads of signed integers");
466 TEST_CASE(
"Check dbuff reads of floating point values");
470 TEST_CHECK(memcmp(&fval1, &fval2,
sizeof(fval1)) == 0);
475 TEST_CHECK(memcmp(&fval1, &fval2,
sizeof(fval1)) == 0);
477 TEST_CASE(
"Check variable length uint64_t read");
491 memset(buff3, 0,
sizeof(buff3));
503 memset(buff3, 0,
sizeof(buff3));
#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.
#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...
struct fr_dbuff_marker_s fr_dbuff_marker_t
A position marker associated with a dbuff.
#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.
#define fr_dbuff_current(_dbuff_or_marker)
Return the 'current' position of a dbuff or marker.
#define fr_dbuff_init(_out, _start, _len_or_end)
Initialise an dbuff for encoding or decoding.
#define fr_dbuff_start(_dbuff_or_marker)
Return the 'start' position of a dbuff or marker.
#define fr_dbuff_set_to_start(_dbuff_or_marker)
Reset the 'current' position of the dbuff or marker to the 'start' of the buffer.
#define fr_dbuff_out_memcpy(_out, _dbuff_or_marker, _outlen)
Copy exactly _outlen bytes from the dbuff.
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.
#define fr_dbuff_remaining(_dbuff_or_marker)
Return the number of bytes remaining between the dbuff or marker and the end of the buffer.
#define fr_dbuff_in_bytes(_dbuff_or_marker,...)
Copy a byte sequence into a dbuff or marker.
#define fr_dbuff_in_uint64v(_dbuff_or_marker, _num)
Copy an integer value into a dbuff or marker using our internal variable length encoding.
#define fr_dbuff_in(_dbuff_or_marker, _in)
Copy data from a fixed sized C type into a dbuff or marker.
#define fr_dbuff_set_to_end(_dbuff_or_marker)
Reset the 'current' position of the dbuff or marker to the 'end' of the buffer.
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.
#define FR_DBUFF(_dbuff_or_marker)
Create a new dbuff pointing to the same underlying buffer.
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.
#define fr_dbuff_move(_out, _in, _len)
Copy in as many bytes as possible from one dbuff or marker to another.
#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.
#define fr_dbuff_out(_out, _dbuff_or_marker)
Copy data from a dbuff or marker to a fixed sized C type.
static void test_dbuff_init_no_parent(void)
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[])
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)
static void test_dbuff_talloc_extend_multi_level(void)
static void test_dbuff_init(void)
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.
static void test_dbuff_move(void)
static void test_dbuff_fd(void)
static void test_dbuff_fd_max(void)
static char buff[sizeof("18446744073709551615")+3]