Skip to content

Commit d433c22

Browse files
committed
check key length in preamble
Error rather than assert, if key length is greater than INT_MAX
1 parent ac49920 commit d433c22

File tree

2 files changed

+50
-10
lines changed

2 files changed

+50
-10
lines changed

src/libbson/src/bson/bson-json.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -347,13 +347,17 @@ _noop (void)
347347
bson->code_data.in_scope = false; \
348348
} while (0)
349349
#define STACK_POP_DBPOINTER STACK_POP_DOC (_noop ())
350-
#define BASIC_CB_PREAMBLE \
351-
const char *key; \
352-
size_t len; \
353-
bson_json_reader_bson_t *bson = &reader->bson; \
354-
_bson_json_read_fixup_key (bson); \
355-
key = bson->key; \
356-
len = bson->key_buf.len; \
350+
#define BASIC_CB_PREAMBLE \
351+
const char *key; \
352+
size_t len; \
353+
bson_json_reader_bson_t *bson = &reader->bson; \
354+
_bson_json_read_fixup_key (bson); \
355+
key = bson->key; \
356+
len = bson->key_buf.len; \
357+
if (len > INT_MAX) { \
358+
_bson_json_read_set_error (reader, "Failed to read JSON. key size %zu is too large. Max is %d", len, INT_MAX); \
359+
return; \
360+
} \
357361
(void) 0
358362
#define BASIC_CB_BAIL_IF_NOT_NORMAL(_type) \
359363
if (bson->read_state != BSON_JSON_REGULAR) { \
@@ -396,7 +400,7 @@ bson_json_opts_new (bson_json_mode_t mode, int32_t max_len)
396400
bson_json_opts_t *opts;
397401

398402
opts = (bson_json_opts_t *) bson_malloc (sizeof *opts);
399-
*opts = (bson_json_opts_t){
403+
*opts = (bson_json_opts_t) {
400404
.mode = mode,
401405
.max_len = max_len,
402406
.is_outermost_array = false,
@@ -622,8 +626,6 @@ _bson_json_read_integer (bson_json_reader_t *reader, uint64_t val, int64_t sign)
622626

623627
if (rs == BSON_JSON_REGULAR) {
624628
BASIC_CB_BAIL_IF_NOT_NORMAL ("integer");
625-
BSON_ASSERT (mlib_in_range (int, len));
626-
627629
if (val <= INT32_MAX || (sign == -1 && val <= (uint64_t) INT32_MAX + 1)) {
628630
bson_append_int32 (STACK_BSON_CHILD, key, (int) len, (int32_t) ((int64_t) val * sign));
629631
} else if (sign == -1) {

src/libbson/tests/test-json.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <common-json-private.h>
1414
#include <bson/bson-iso8601-private.h>
1515
#include <bson/bson-json-private.h>
16+
#include "test-libmongoc.h" // skip_if_no_large_allocations
1617

1718
static ssize_t
1819
test_bson_json_read_cb_helper (void *string, uint8_t *buf, size_t len)
@@ -3793,6 +3794,42 @@ test_bson_as_json_all_formats (void)
37933794
}
37943795
}
37953796

3797+
static void
3798+
test_json_big_key (void *unused)
3799+
{
3800+
BSON_UNUSED (unused);
3801+
3802+
// Create a JSON string like: { "<'a' repeated INT_MAX + 1 times>": 123 }
3803+
size_t keylen = INT_MAX + 1u;
3804+
size_t json_len = strlen ("{\"") + keylen + strlen ("\":123}");
3805+
char *json = bson_malloc (json_len + 1);
3806+
json[json_len] = '\0';
3807+
3808+
size_t offset = 0;
3809+
// Write {"
3810+
{
3811+
bson_strncpy (json, "{\"", json_len + 1);
3812+
offset += strlen ("{\"");
3813+
}
3814+
// Write key of repeated a
3815+
{
3816+
for (size_t i = 0; i < keylen; i++) {
3817+
json[offset++] = 'a';
3818+
}
3819+
}
3820+
// Write remaining ":123}
3821+
{
3822+
bson_strncpy (json + offset, "\":123}", json_len + 1 - offset);
3823+
offset += strlen ("\":123}");
3824+
}
3825+
3826+
bson_error_t error;
3827+
bson_t b;
3828+
bool ok = bson_init_from_json (&b, json, (ssize_t) json_len, &error);
3829+
ASSERT (!ok);
3830+
ASSERT_ERROR_CONTAINS (error, BSON_ERROR_JSON, BSON_JSON_ERROR_READ_INVALID_PARAM, "too large");
3831+
bson_free (json);
3832+
}
37963833

37973834
void
37983835
test_json_install (TestSuite *suite)
@@ -3899,4 +3936,5 @@ test_json_install (TestSuite *suite)
38993936
TestSuite_Add (suite, "/bson/parse_array", test_parse_array);
39003937
TestSuite_Add (suite, "/bson/decimal128_overflowing_exponent", test_decimal128_overflowing_exponent);
39013938
TestSuite_Add (suite, "/bson/as_json/all_formats", test_bson_as_json_all_formats);
3939+
TestSuite_AddFull (suite, "/bson/json/big_key", test_json_big_key, NULL, NULL, skip_if_no_large_allocations);
39023940
}

0 commit comments

Comments
 (0)