Skip to content

Commit

Permalink
cJSON_Compare: Fix comparison of objects
Browse files Browse the repository at this point in the history
It did consider two arrays equal if one is a subset of te other one,
which is incorrect.

See #180
  • Loading branch information
FSMaxB committed Jun 14, 2017
1 parent 569aa06 commit 03ba72f
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
19 changes: 18 additions & 1 deletion cJSON.c
Original file line number Diff line number Diff line change
Expand Up @@ -2605,10 +2605,11 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons
case cJSON_Object:
{
cJSON *a_element = NULL;
cJSON *b_element = NULL;
cJSON_ArrayForEach(a_element, a)
{
/* TODO This has O(n^2) runtime, which is horrible! */
cJSON *b_element = get_object_item(b, a_element->string, case_sensitive);
b_element = get_object_item(b, a_element->string, case_sensitive);
if (b_element == NULL)
{
return false;
Expand All @@ -2620,6 +2621,22 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons
}
}

/* doing this twice, once on a and b to prevent true comparison if a subset of b
* TODO: Do this the proper way, this is just a fix for now */
cJSON_ArrayForEach(b_element, b)
{
a_element = get_object_item(a, b_element->string, case_sensitive);
if (a_element == NULL)
{
return false;
}

if (!cJSON_Compare(b_element, a_element, case_sensitive))
{
return false;
}
}

return true;
}

Expand Down
9 changes: 9 additions & 0 deletions tests/compare_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,15 @@ static void cjson_compare_should_compare_objects(void)
"{\"Flse\": false, \"true\": true, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
"{\"true\": true, \"false\": false, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
false));
/* test objects that are a subset of each other */
TEST_ASSERT_FALSE(compare_from_string(
"{\"one\": 1, \"two\": 2}",
"{\"one\": 1, \"two\": 2, \"three\": 3}",
true))
TEST_ASSERT_FALSE(compare_from_string(
"{\"one\": 1, \"two\": 2}",
"{\"one\": 1, \"two\": 2, \"three\": 3}",
false))
}

int main(void)
Expand Down

0 comments on commit 03ba72f

Please sign in to comment.