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: 13 additions & 1 deletion src/flb_pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -1163,9 +1163,21 @@ int flb_msgpack_to_json(char *json_str, size_t json_size,
return -1;
}

/* a zero-capacity buffer would wrap 'json_size - 1' to SIZE_MAX below */
if (json_size == 0) {
return -1;
}

ret = msgpack2json(json_str, &off, json_size - 1, obj, escape_unicode);
json_str[off] = '\0';
return ret ? off: ret;

/*
* msgpack2json() returns FLB_FALSE (0) when the output did not fit in the
* buffer. Report that as a negative value so fixed-buffer callers can
* distinguish truncation from a successful zero-length write, matching the
* documented contract above.
*/
return ret ? off : -1;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Comment thread
cosmo0920 marked this conversation as resolved.
}

flb_sds_t flb_msgpack_raw_to_json_sds(const void *in_buf, size_t in_size, int escape_unicode)
Expand Down
42 changes: 42 additions & 0 deletions tests/internal/pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,47 @@ void test_json_pack_nan()
flb_pack_init(&config);
}

/*
* flb_msgpack_to_json() must report a buffer overflow as a negative value
* (not 0), so fixed-buffer callers can tell truncation apart from a
* successful zero-length write.
*/
void test_json_pack_truncation()
{
int ret;
char small[4];
msgpack_sbuffer mp_sbuf;
msgpack_packer mp_pck;
msgpack_object obj;
msgpack_zone mempool;
msgpack_unpack_return unpack_ret;

/* a value whose JSON form does not fit in the destination buffer */
msgpack_sbuffer_init(&mp_sbuf);
msgpack_packer_init(&mp_pck, &mp_sbuf, msgpack_sbuffer_write);
msgpack_pack_double(&mp_pck, 123456789.0);
msgpack_zone_init(&mempool, 2048);
unpack_ret = msgpack_unpack(mp_sbuf.data, mp_sbuf.size, NULL, &mempool, &obj);
if (!TEST_CHECK(unpack_ret == MSGPACK_UNPACK_SUCCESS)) {
TEST_MSG("msgpack_unpack failed: %d", unpack_ret);
msgpack_zone_destroy(&mempool);
msgpack_sbuffer_destroy(&mp_sbuf);
return;
}

ret = flb_msgpack_to_json(small, sizeof(small), &obj, FLB_TRUE);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
if (!TEST_CHECK(ret < 0)) {
TEST_MSG("truncation must return a negative value, got %d", ret);
}

/* a zero-capacity buffer must be rejected, not wrapped to SIZE_MAX */
ret = flb_msgpack_to_json(small, 0, &obj, FLB_TRUE);
TEST_CHECK(ret < 0);

msgpack_zone_destroy(&mempool);
msgpack_sbuffer_destroy(&mp_sbuf);
}

static int check_msgpack_val(msgpack_object obj, int expected_type, char *expected_val)
{
int len;
Expand Down Expand Up @@ -1303,6 +1344,7 @@ TEST_LIST = {
{ "json_pack_bug342" , test_json_pack_bug342},
{ "json_pack_bug1278" , test_json_pack_bug1278},
{ "json_pack_nan" , test_json_pack_nan},
{ "json_pack_truncation", test_json_pack_truncation},
{ "json_pack_bug5336" , test_json_pack_bug5336},
{ "json_pack_empty_array", test_json_pack_empty_array},
{ "json_date_iso8601" , test_json_date_iso8601},
Expand Down
Loading