diff options
Diffstat (limited to 'src/json/json.c')
-rw-r--r-- | src/json/json.c | 234 |
1 files changed, 42 insertions, 192 deletions
diff --git a/src/json/json.c b/src/json/json.c index d4ac37489..639bd530c 100644 --- a/src/json/json.c +++ b/src/json/json.c @@ -62,170 +62,6 @@ contains_real (const json_t *json) /** - * Dump character in the low range into @a buf - * following RFC 8785. - * - * @param[in,out] buf buffer to modify - * @param val value to dump - */ -static void -lowdump (struct GNUNET_Buffer *buf, - unsigned char val) -{ - char scratch[7]; - - switch (val) - { - case 0x8: - GNUNET_buffer_write (buf, - "\\b", - 2); - break; - case 0x9: - GNUNET_buffer_write (buf, - "\\t", - 2); - break; - case 0xA: - GNUNET_buffer_write (buf, - "\\n", - 2); - break; - case 0xC: - GNUNET_buffer_write (buf, - "\\f", - 2); - break; - case 0xD: - GNUNET_buffer_write (buf, - "\\r", - 2); - break; - default: - GNUNET_snprintf (scratch, - sizeof (scratch), - "\\u%04x", - (unsigned int) val); - GNUNET_buffer_write (buf, - scratch, - 6); - break; - } -} - - -/** - * Re-encode string at @a inp to match RFC 8785 (section 3.2.2.2). - * - * @param[in,out] inp pointer to string to re-encode - * @return number of bytes in resulting @a inp - */ -static size_t -rfc8785encode (char **inp) -{ - struct GNUNET_Buffer buf = { 0 }; - size_t left = strlen (*inp) + 1; - size_t olen; - char *in = *inp; - const char *pos = in; - - GNUNET_buffer_prealloc (&buf, - left + 40); - buf.warn_grow = 0; /* disable, + 40 is just a wild guess */ - while (1) - { - int mbl = u8_mblen ((unsigned char *) pos, - left); - unsigned char val; - - if (0 == mbl) - break; - val = (unsigned char) *pos; - if ( (1 == mbl) && - (val <= 0x1F) ) - { - /* Should not happen, as input is produced by - * JSON stringification */ - GNUNET_break (0); - lowdump (&buf, - val); - } - else if ( (1 == mbl) && ('\\' == *pos) ) - { - switch (*(pos + 1)) - { - case '\\': - mbl = 2; - GNUNET_buffer_write (&buf, - pos, - mbl); - break; - case 'u': - { - unsigned int num; - uint32_t n32; - unsigned char res[8]; - size_t rlen; - - GNUNET_assert ( (1 == - sscanf (pos + 2, - "%4x", - &num)) || - (1 == - sscanf (pos + 2, - "%4X", - &num)) ); - mbl = 6; - n32 = (uint32_t) num; - rlen = sizeof (res); - u32_to_u8 (&n32, - 1, - res, - &rlen); - if ( (1 == rlen) && - (res[0] <= 0x1F) ) - { - lowdump (&buf, - res[0]); - } - else - { - GNUNET_buffer_write (&buf, - (const char *) res, - rlen); - } - } - break; - default: - mbl = 2; - GNUNET_buffer_write (&buf, - pos, - mbl); - break; - } - } - else - { - GNUNET_buffer_write (&buf, - pos, - mbl); - } - left -= mbl; - pos += mbl; - } - - /* 0-terminate buffer */ - GNUNET_buffer_write (&buf, - "", - 1); - GNUNET_free (in); - *inp = GNUNET_buffer_reap (&buf, - &olen); - return olen; -} - - -/** * Dump the @a json to a string and hash it. * * @param json value to hash @@ -262,7 +98,7 @@ dump_and_hash (const json_t *json, GNUNET_break (0); return GNUNET_SYSERR; } - len = rfc8785encode (&wire_enc); + len = TALER_rfc8785encode (&wire_enc); if (NULL == salt) { GNUNET_CRYPTO_hash (wire_enc, @@ -697,7 +533,7 @@ TALER_JSON_contract_part_forget (json_t *json, /** - * Look over all of the values of a '$forgettable' object. Replace 'True' + * Loop over all of the values of a '$forgettable' object. Replace 'True' * values with proper random salts. Fails if any forgettable values are * neither 'True' nor valid salts (strings). * @@ -742,51 +578,64 @@ seed_forgettable (json_t *f) } -/** - * Take a given contract with "forgettable" fields marked - * but with 'True' instead of a real salt. Replaces all - * 'True' values with proper random salts. Fails if any - * forgettable markers are neither 'True' nor valid salts. - * - * @param[in,out] json JSON to transform - * @return #GNUNET_OK on success - */ enum GNUNET_GenericReturnValue -TALER_JSON_contract_seed_forgettable (json_t *json) +TALER_JSON_contract_seed_forgettable (const json_t *spec, + json_t *contract) { - if (json_is_object (json)) + if (json_is_object (spec)) { const char *key; json_t *val; - json_object_foreach (json, + json_object_foreach ((json_t *) spec, key, val) { + json_t *cval = json_object_get (contract, + key); + if (0 == strcmp ("$forgettable", key)) { + json_t *xval = json_deep_copy (val); + if (GNUNET_OK != - seed_forgettable (val)) + seed_forgettable (xval)) + { + json_decref (xval); return GNUNET_SYSERR; + } + GNUNET_assert (0 == + json_object_set_new (contract, + "$forgettable", + xval)); continue; } + if (NULL == cval) + continue; if (GNUNET_OK != - TALER_JSON_contract_seed_forgettable (val)) + TALER_JSON_contract_seed_forgettable (val, + cval)) return GNUNET_SYSERR; } } - if (json_is_array (json)) + if (json_is_array (spec)) { size_t index; json_t *val; - json_array_foreach (json, + json_array_foreach ((json_t *) spec, index, val) { + json_t *ival = json_array_get (contract, + index); + + if (NULL == ival) + continue; if (GNUNET_OK != - TALER_JSON_contract_seed_forgettable (val)) + TALER_JSON_contract_seed_forgettable (val, + ival)) return GNUNET_SYSERR; } } @@ -819,6 +668,7 @@ parse_path (json_t *obj, json_t *next_obj = NULL; char *next_dot; + GNUNET_assert (NULL != id); /* make stupid compiler happy */ if (NULL == next_id) { cb (cb_cls, @@ -1008,12 +858,12 @@ TALER_JSON_get_error_code2 (const void *data, void -TALER_deposit_extension_hash (const json_t *extensions, - struct TALER_ExtensionContractHashP *ech) +TALER_deposit_policy_hash (const json_t *policy, + struct TALER_ExtensionPolicyHashP *ech) { GNUNET_assert (GNUNET_OK == - dump_and_hash (extensions, - "taler-contract-extensions", + dump_and_hash (policy, + "taler-extensions-policy", &ech->hash)); } @@ -1031,17 +881,17 @@ TALER_JSON_canonicalize (const json_t *input) GNUNET_break (0); return NULL; } - rfc8785encode (&wire_enc); + TALER_rfc8785encode (&wire_enc); return wire_enc; } enum GNUNET_GenericReturnValue -TALER_JSON_extensions_config_hash (const json_t *config, - struct TALER_ExtensionConfigHashP *ech) +TALER_JSON_extensions_manifests_hash (const json_t *manifests, + struct TALER_ExtensionManifestsHashP *ech) { - return dump_and_hash (config, - "taler-extension-configuration", + return dump_and_hash (manifests, + "taler-extensions-manifests", &ech->hash); } |