diff --git a/cJSON.c b/cJSON.c index 51fded7..e32f7ca 100644 --- a/cJSON.c +++ b/cJSON.c @@ -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; @@ -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; } diff --git a/tests/compare_tests.c b/tests/compare_tests.c index 5984268..63b6d4a 100644 --- a/tests/compare_tests.c +++ b/tests/compare_tests.c @@ -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)