Skip to content

Commit 03ba72f

Browse files
committed
cJSON_Compare: Fix comparison of objects
It did consider two arrays equal if one is a subset of te other one, which is incorrect. See #180
1 parent 569aa06 commit 03ba72f

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

cJSON.c

+18-1
Original file line numberDiff line numberDiff line change
@@ -2605,10 +2605,11 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons
26052605
case cJSON_Object:
26062606
{
26072607
cJSON *a_element = NULL;
2608+
cJSON *b_element = NULL;
26082609
cJSON_ArrayForEach(a_element, a)
26092610
{
26102611
/* TODO This has O(n^2) runtime, which is horrible! */
2611-
cJSON *b_element = get_object_item(b, a_element->string, case_sensitive);
2612+
b_element = get_object_item(b, a_element->string, case_sensitive);
26122613
if (b_element == NULL)
26132614
{
26142615
return false;
@@ -2620,6 +2621,22 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons
26202621
}
26212622
}
26222623

2624+
/* doing this twice, once on a and b to prevent true comparison if a subset of b
2625+
* TODO: Do this the proper way, this is just a fix for now */
2626+
cJSON_ArrayForEach(b_element, b)
2627+
{
2628+
a_element = get_object_item(a, b_element->string, case_sensitive);
2629+
if (a_element == NULL)
2630+
{
2631+
return false;
2632+
}
2633+
2634+
if (!cJSON_Compare(b_element, a_element, case_sensitive))
2635+
{
2636+
return false;
2637+
}
2638+
}
2639+
26232640
return true;
26242641
}
26252642

tests/compare_tests.c

+9
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,15 @@ static void cjson_compare_should_compare_objects(void)
175175
"{\"Flse\": false, \"true\": true, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
176176
"{\"true\": true, \"false\": false, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
177177
false));
178+
/* test objects that are a subset of each other */
179+
TEST_ASSERT_FALSE(compare_from_string(
180+
"{\"one\": 1, \"two\": 2}",
181+
"{\"one\": 1, \"two\": 2, \"three\": 3}",
182+
true))
183+
TEST_ASSERT_FALSE(compare_from_string(
184+
"{\"one\": 1, \"two\": 2}",
185+
"{\"one\": 1, \"two\": 2, \"three\": 3}",
186+
false))
178187
}
179188

180189
int main(void)

0 commit comments

Comments
 (0)