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
This commit is contained in:
Max Bruckner 2017-06-13 08:48:41 +02:00
parent 569aa060c6
commit 03ba72faec
2 changed files with 27 additions and 1 deletions

19
cJSON.c
View File

@ -2605,10 +2605,11 @@ CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * cons
case cJSON_Object: case cJSON_Object:
{ {
cJSON *a_element = NULL; cJSON *a_element = NULL;
cJSON *b_element = NULL;
cJSON_ArrayForEach(a_element, a) cJSON_ArrayForEach(a_element, a)
{ {
/* TODO This has O(n^2) runtime, which is horrible! */ /* 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) if (b_element == NULL)
{ {
return false; return false;
@ -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; return true;
} }

View File

@ -175,6 +175,15 @@ static void cjson_compare_should_compare_objects(void)
"{\"Flse\": false, \"true\": true, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}", "{\"Flse\": false, \"true\": true, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
"{\"true\": true, \"false\": false, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}", "{\"true\": true, \"false\": false, \"null\": null, \"number\": 42, \"string\": \"string\", \"array\": [], \"object\": {}}",
false)); 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) int main(void)