Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions include/ctraces/ctr_variant_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
#define CFL_VARIANT_UTILS_INITIAL_ARRAY_SIZE 100
#define CFL_VARIANT_UTILS_SERIALIZED_ARRAY_SIZE_LIMIT 100000
#define CFL_VARIANT_UTILS_SERIALIZED_MAP_SIZE_LIMIT 100000
#define CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH 64
#define CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH 32
#define CFL_VARIANT_UTILS_MAXIMUM_KEY_LENGTH (1024 * 1000)

/* These are the only functions meant for general use,
Expand Down Expand Up @@ -246,6 +246,10 @@ static inline int unpack_cfl_array_depth(mpack_reader_t *reader,
size_t index;
mpack_tag_t tag;

if (depth >= CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH) {
return -2;
}

result = unpack_cfl_variant_read_tag(reader, &tag, mpack_type_array);

if (result != 0) {
Expand Down Expand Up @@ -318,6 +322,10 @@ static inline int unpack_cfl_kvlist_depth(mpack_reader_t *reader,
size_t index;
mpack_tag_t tag;

if (depth >= CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH) {
return -2;
}

result = unpack_cfl_variant_read_tag(reader, &tag, mpack_type_map);

if (result != 0) {
Expand Down Expand Up @@ -670,10 +678,6 @@ static inline int unpack_cfl_variant_depth(mpack_reader_t *reader,
int result;
mpack_tag_t tag;

if (depth >= CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH) {
return -1;
}

tag = mpack_peek_tag(reader);

if (mpack_ok != mpack_reader_error(reader)) {
Expand Down
59 changes: 51 additions & 8 deletions tests/decoding.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,32 +716,75 @@ void test_msgpack_long_attribute_key()
ctr_destroy(ctx);
}

void test_msgpack_variant_limits()
static void check_variant_nesting_limit(int use_maps, size_t nesting_depth,
int expected_result)
{
char *buffer;
size_t size;
int index;
size_t index;
int result;
mpack_writer_t writer;
mpack_reader_t reader;
struct cfl_variant *variant;
struct cfl_kvlist *kvlist;

buffer = NULL;
size = 0;
variant = NULL;
mpack_writer_init_growable(&writer, &buffer, &size);
for (index = 0; index < CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH + 1; index++) {
mpack_start_array(&writer, 1);

for (index = 0; index < nesting_depth; index++) {
if (use_maps) {
mpack_start_map(&writer, 1);
mpack_write_cstr(&writer, "key");
}
else {
mpack_start_array(&writer, 1);
}
}

mpack_write_i64(&writer, 1);
for (index = 0; index < CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH + 1; index++) {
mpack_finish_array(&writer);

for (index = 0; index < nesting_depth; index++) {
if (use_maps) {
mpack_finish_map(&writer);
}
else {
mpack_finish_array(&writer);
}
}

TEST_ASSERT(mpack_writer_destroy(&writer) == mpack_ok);

mpack_reader_init_data(&reader, buffer, size);
result = unpack_cfl_variant(&reader, &variant);
TEST_CHECK(result != 0);
TEST_CHECK((result == 0) == (expected_result == 0));

if (variant != NULL) {
cfl_variant_destroy(variant);
}

mpack_reader_destroy(&reader);
free(buffer);
}

void test_msgpack_variant_limits()
{
char *buffer;
size_t size;
int result;
mpack_writer_t writer;
mpack_reader_t reader;
struct cfl_variant *variant;
struct cfl_kvlist *kvlist;

check_variant_nesting_limit(CFL_FALSE,
CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH, 0);
check_variant_nesting_limit(CFL_FALSE,
CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH + 1, -1);
check_variant_nesting_limit(CFL_TRUE,
CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH, 0);
check_variant_nesting_limit(CFL_TRUE,
CFL_VARIANT_UTILS_MAXIMUM_NESTING_DEPTH + 1, -1);

mpack_writer_init_growable(&writer, &buffer, &size);
mpack_start_map(&writer, 1);
Expand Down
Loading