mirror of
https://github.com/DaveGamble/cJSON.git
synced 2024-12-25 20:30:50 +08:00
Added max recusrion depth for cJSONDuplicate to prevent stack exhaustion in case of circular reference
This commit is contained in:
parent
078c4e6c53
commit
9d1b229086
12
cJSON.c
12
cJSON.c
@ -2737,7 +2737,14 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int co
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Duplication */
|
/* Duplication */
|
||||||
|
cJSON * cJSON_Duplicate_rec(const cJSON *item, size_t depth, cJSON_bool recurse);
|
||||||
|
|
||||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
|
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
|
||||||
|
{
|
||||||
|
return cJSON_Duplicate_rec(item, 0, recurse );
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON * cJSON_Duplicate_rec(const cJSON *item, size_t depth, cJSON_bool recurse)
|
||||||
{
|
{
|
||||||
cJSON *newitem = NULL;
|
cJSON *newitem = NULL;
|
||||||
cJSON *child = NULL;
|
cJSON *child = NULL;
|
||||||
@ -2784,7 +2791,10 @@ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse)
|
|||||||
child = item->child;
|
child = item->child;
|
||||||
while (child != NULL)
|
while (child != NULL)
|
||||||
{
|
{
|
||||||
newchild = cJSON_Duplicate(child, true); /* Duplicate (with recurse) each item in the ->next chain */
|
if(depth >= CJSON_CIRCULAR_LIMIT) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
newchild = cJSON_Duplicate_rec(child, ++depth, true); /* Duplicate (with recurse) each item in the ->next chain */
|
||||||
if (!newchild)
|
if (!newchild)
|
||||||
{
|
{
|
||||||
goto fail;
|
goto fail;
|
||||||
|
6
cJSON.h
6
cJSON.h
@ -137,6 +137,12 @@ typedef int cJSON_bool;
|
|||||||
#define CJSON_NESTING_LIMIT 1000
|
#define CJSON_NESTING_LIMIT 1000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Limits the length of circular references can be before cJSON rejects to parse them.
|
||||||
|
* This is to prevent stack overflows. */
|
||||||
|
#ifndef CJSON_CIRCULAR_LIMIT
|
||||||
|
#define CJSON_CIRCULAR_LIMIT 10000
|
||||||
|
#endif
|
||||||
|
|
||||||
/* returns the version of cJSON as a string */
|
/* returns the version of cJSON as a string */
|
||||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||||
|
|
||||||
|
@ -219,6 +219,23 @@ static void cjson_should_not_parse_to_deeply_nested_jsons(void)
|
|||||||
TEST_ASSERT_NULL_MESSAGE(cJSON_Parse(deep_json), "To deep JSONs should not be parsed.");
|
TEST_ASSERT_NULL_MESSAGE(cJSON_Parse(deep_json), "To deep JSONs should not be parsed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cjson_should_not_follow_too_deep_circular_references(void)
|
||||||
|
{
|
||||||
|
cJSON *o = cJSON_CreateArray();
|
||||||
|
cJSON *a = cJSON_CreateArray();
|
||||||
|
cJSON *b = cJSON_CreateArray();
|
||||||
|
cJSON *x;
|
||||||
|
|
||||||
|
cJSON_AddItemToArray(o, a);
|
||||||
|
cJSON_AddItemToArray(a, b);
|
||||||
|
cJSON_AddItemToArray(b, o);
|
||||||
|
|
||||||
|
x = cJSON_Duplicate(o, 1);
|
||||||
|
TEST_ASSERT_NULL(x);
|
||||||
|
cJSON_DetachItemFromArray(b, 0);
|
||||||
|
cJSON_Delete(o);
|
||||||
|
}
|
||||||
|
|
||||||
static void cjson_set_number_value_should_set_numbers(void)
|
static void cjson_set_number_value_should_set_numbers(void)
|
||||||
{
|
{
|
||||||
cJSON number[1] = {{NULL, NULL, NULL, cJSON_Number, NULL, 0, 0, NULL}};
|
cJSON number[1] = {{NULL, NULL, NULL, cJSON_Number, NULL, 0, 0, NULL}};
|
||||||
@ -777,6 +794,7 @@ int CJSON_CDECL main(void)
|
|||||||
RUN_TEST(cjson_get_object_item_case_sensitive_should_not_crash_with_array);
|
RUN_TEST(cjson_get_object_item_case_sensitive_should_not_crash_with_array);
|
||||||
RUN_TEST(typecheck_functions_should_check_type);
|
RUN_TEST(typecheck_functions_should_check_type);
|
||||||
RUN_TEST(cjson_should_not_parse_to_deeply_nested_jsons);
|
RUN_TEST(cjson_should_not_parse_to_deeply_nested_jsons);
|
||||||
|
RUN_TEST(cjson_should_not_follow_too_deep_circular_references);
|
||||||
RUN_TEST(cjson_set_number_value_should_set_numbers);
|
RUN_TEST(cjson_set_number_value_should_set_numbers);
|
||||||
RUN_TEST(cjson_detach_item_via_pointer_should_detach_items);
|
RUN_TEST(cjson_detach_item_via_pointer_should_detach_items);
|
||||||
RUN_TEST(cjson_detach_item_via_pointer_should_return_null_if_item_prev_is_null);
|
RUN_TEST(cjson_detach_item_via_pointer_should_return_null_if_item_prev_is_null);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user