diff --git a/src/json/json.c b/src/json/json.c index 4874f0c21..9ee1628e9 100644 --- a/src/json/json.c +++ b/src/json/json.c @@ -41,8 +41,11 @@ dump_and_hash (const json_t *json, char *wire_enc; size_t len; + GNUNET_break (NULL != json); if (NULL == (wire_enc = json_dumps (json, - JSON_COMPACT | JSON_SORT_KEYS))) + JSON_ENCODE_ANY + | JSON_COMPACT + | JSON_SORT_KEYS))) { GNUNET_break (0); return GNUNET_SYSERR; @@ -116,7 +119,7 @@ forget (const json_t *in) } return ret; } - if (! json_is_object (in)) + if (json_is_object (in)) { json_t *ret; const char *key; @@ -147,6 +150,23 @@ forget (const json_t *in) continue; /* skip! */ if (rx == value) continue; /* skip! */ + if ( (NULL != rx) && + (NULL != + json_object_get (rx, + key)) ) + { + if (0 != + json_object_set_new (ret, + key, + json_null ())) + { + GNUNET_break (0); + json_decref (ret); + json_decref (rx); + return NULL; + } + continue; /* already forgotten earlier */ + } t = forget (value); if (NULL == t) { @@ -208,7 +228,6 @@ forget (const json_t *in) json_decref (rx); return NULL; } - } else { @@ -225,10 +244,11 @@ forget (const json_t *in) } } } /* json_object_foreach */ - if (0 != - json_object_set_new (ret, - "_forgotten", - rx)) + if ( (NULL != rx) && + (0 != + json_object_set_new (ret, + "_forgotten", + rx)) ) { GNUNET_break (0); json_decref (ret); diff --git a/src/json/test_json.c b/src/json/test_json.c index 2e7aba50a..e876d95db 100644 --- a/src/json/test_json.c +++ b/src/json/test_json.c @@ -56,6 +56,74 @@ test_amount (void) } +static int +test_contract () +{ + struct GNUNET_HashCode h1; + struct GNUNET_HashCode h2; + json_t *c1; + json_t *c2; + json_t *c3; + + c1 = json_pack ("{s:s, s:{s:s, s:{s:s}}}", + "k1", "v1", + "k2", "n1", "n2", + /***/ "_forgettable", "n1", "salt"); + GNUNET_assert (NULL != c1); + GNUNET_assert (GNUNET_OK == + TALER_JSON_contract_mark_forgettable (c1, + "k1")); + GNUNET_assert (GNUNET_OK == + TALER_JSON_contract_hash (c1, + &h1)); + GNUNET_assert (GNUNET_OK == + TALER_JSON_contract_part_forget (c1, + "k1")); + GNUNET_assert (GNUNET_OK == + TALER_JSON_contract_hash (c1, + &h2)); + json_decref (c1); + if (0 != + GNUNET_memcmp (&h1, + &h2)) + { + GNUNET_break (0); + return 1; + } + c2 = json_pack ("{s:s}", + "n1", "n2"); + GNUNET_assert (NULL != c2); + GNUNET_assert (GNUNET_OK == + TALER_JSON_contract_mark_forgettable (c2, + "n1")); + c3 = json_pack ("{s:s, s:o}", + "k1", "v1", + "k2", c2); + GNUNET_assert (NULL != c3); + GNUNET_assert (GNUNET_OK == + TALER_JSON_contract_mark_forgettable (c3, + "k1")); + GNUNET_assert (GNUNET_OK == + TALER_JSON_contract_hash (c3, + &h1)); + GNUNET_assert (GNUNET_OK == + TALER_JSON_contract_part_forget (c2, + "n1")); + GNUNET_assert (GNUNET_OK == + TALER_JSON_contract_hash (c3, + &h2)); + json_decref (c3); + if (0 != + GNUNET_memcmp (&h1, + &h2)) + { + GNUNET_break (0); + return 1; + } + return 0; +} + + int main (int argc, const char *const argv[]) @@ -67,6 +135,8 @@ main (int argc, NULL); if (0 != test_amount ()) return 1; + if (0 != test_contract ()) + return 2; return 0; }