gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated: code cleanup, fixing misc. memor


From: gnunet
Subject: [taler-exchange] branch master updated: code cleanup, fixing misc. memory leaks in the process
Date: Sun, 04 Jun 2023 13:26:06 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 80930015 code cleanup, fixing misc. memory leaks in the process
80930015 is described below

commit 809300158caaa0215c36ef89c7e38f0edfa93593
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun Jun 4 13:26:00 2023 +0200

    code cleanup, fixing misc. memory leaks in the process
---
 src/exchange-tools/taler-auditor-offline.c         | 16 ++---
 src/exchange-tools/taler-exchange-offline.c        | 78 +++++++++-------------
 .../taler-exchange-httpd_age-withdraw_reveal.c     | 34 ++++++----
 src/exchange/taler-exchange-httpd_aml-decision.c   | 21 +-----
 src/exchange/taler-exchange-httpd_batch-deposit.c  |  6 +-
 src/exchange/taler-exchange-httpd_batch-withdraw.c | 14 ++--
 src/exchange/taler-exchange-httpd_csr.c            | 10 ++-
 .../taler-exchange-httpd_management_extensions.c   | 28 ++------
 .../taler-exchange-httpd_management_post_keys.c    | 27 ++------
 .../taler-exchange-httpd_management_wire_enable.c  | 12 ++--
 src/exchange/taler-exchange-httpd_purses_create.c  | 17 +----
 src/exchange/taler-exchange-httpd_purses_deposit.c | 11 +--
 .../taler-exchange-httpd_refreshes_reveal.c        | 51 ++++++--------
 .../taler-exchange-httpd_reserves_attest.c         |  6 +-
 src/exchange/taler-exchange-httpd_reserves_open.c  |  7 +-
 src/exchangedb/pg_insert_wire.c                    |  4 +-
 src/exchangedb/pg_insert_wire.h                    |  4 +-
 src/exchangedb/pg_update_wire.c                    |  4 +-
 src/exchangedb/pg_update_wire.h                    |  4 +-
 src/extensions/extensions.c                        | 40 ++++++-----
 src/include/taler_exchange_service.h               |  4 +-
 src/include/taler_exchangedb_plugin.h              |  8 +--
 src/include/taler_extensions.h                     | 12 ++--
 src/kyclogic/plugin_kyclogic_kycaid.c              | 18 ++---
 src/kyclogic/plugin_kyclogic_oauth2.c              |  9 +--
 src/kyclogic/plugin_kyclogic_persona.c             | 45 ++++---------
 src/lib/exchange_api_batch_deposit.c               | 11 +--
 src/lib/exchange_api_common.c                      | 23 +++----
 src/lib/exchange_api_handle.c                      | 30 ++++-----
 src/lib/exchange_api_kyc_check.c                   |  6 +-
 src/lib/exchange_api_link.c                        | 27 ++------
 src/lib/exchange_api_lookup_aml_decision.c         | 25 ++++---
 src/lib/exchange_api_lookup_aml_decisions.c        |  6 +-
 src/lib/exchange_api_management_get_keys.c         | 18 +++--
 src/lib/exchange_api_refreshes_reveal.c            | 17 +----
 src/lib/exchange_api_refund.c                      | 37 ++--------
 src/lib/exchange_api_reserves_attest.c             |  6 +-
 src/lib/exchange_api_reserves_get_attestable.c     |  8 +--
 src/lib/exchange_api_reserves_history.c            |  8 +--
 src/lib/exchange_api_reserves_status.c             |  7 +-
 src/lib/exchange_api_transfers_get.c               | 13 +---
 41 files changed, 275 insertions(+), 457 deletions(-)

diff --git a/src/exchange-tools/taler-auditor-offline.c 
b/src/exchange-tools/taler-auditor-offline.c
index f239c11a..cd439d23 100644
--- a/src/exchange-tools/taler-auditor-offline.c
+++ b/src/exchange-tools/taler-auditor-offline.c
@@ -949,11 +949,11 @@ do_show (char *const *args)
   json_t *keys;
   const char *err_name;
   unsigned int err_line;
-  json_t *denomkeys;
+  const json_t *denomkeys;
   struct TALER_MasterPublicKeyP mpub;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("denoms",
-                           &denomkeys),
+    GNUNET_JSON_spec_array_const ("denoms",
+                                  &denomkeys),
     GNUNET_JSON_spec_fixed_auto ("master_public_key",
                                  &mpub),
     GNUNET_JSON_spec_end ()
@@ -997,11 +997,9 @@ do_show (char *const *args)
   {
     global_ret = EXIT_FAILURE;
     test_shutdown ();
-    GNUNET_JSON_parse_free (spec);
     json_decref (keys);
     return;
   }
-  GNUNET_JSON_parse_free (spec);
   json_decref (keys);
   /* do NOT consume input if next argument is '-' */
   if ( (NULL != args[0]) &&
@@ -1138,10 +1136,10 @@ do_sign (char *const *args)
   const char *err_name;
   unsigned int err_line;
   struct TALER_MasterPublicKeyP mpub;
-  json_t *denomkeys;
+  const json_t *denomkeys;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("denoms",
-                           &denomkeys),
+    GNUNET_JSON_spec_array_const ("denoms",
+                                  &denomkeys),
     GNUNET_JSON_spec_fixed_auto ("master_public_key",
                                  &mpub),
     GNUNET_JSON_spec_end ()
@@ -1196,11 +1194,9 @@ do_sign (char *const *args)
   {
     global_ret = EXIT_FAILURE;
     test_shutdown ();
-    GNUNET_JSON_parse_free (spec);
     json_decref (keys);
     return;
   }
-  GNUNET_JSON_parse_free (spec);
   json_decref (keys);
   next (args);
 }
diff --git a/src/exchange-tools/taler-exchange-offline.c 
b/src/exchange-tools/taler-exchange-offline.c
index b1aababc..77c163c3 100644
--- a/src/exchange-tools/taler-exchange-offline.c
+++ b/src/exchange-tools/taler-exchange-offline.c
@@ -1539,8 +1539,8 @@ upload_wire_add (const char *exchange_url,
   struct WireAddRequest *war;
   const char *err_name;
   const char *conversion_url = NULL;
-  json_t *debit_restrictions;
-  json_t *credit_restrictions;
+  const json_t *debit_restrictions;
+  const json_t *credit_restrictions;
   unsigned int err_line;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_string ("payto_uri",
@@ -1549,10 +1549,10 @@ upload_wire_add (const char *exchange_url,
       GNUNET_JSON_spec_string ("conversion_url",
                                &conversion_url),
       NULL),
-    GNUNET_JSON_spec_json ("debit_restrictions",
-                           &debit_restrictions),
-    GNUNET_JSON_spec_json ("credit_restrictions",
-                           &credit_restrictions),
+    GNUNET_JSON_spec_array_const ("debit_restrictions",
+                                  &debit_restrictions),
+    GNUNET_JSON_spec_array_const ("credit_restrictions",
+                                  &credit_restrictions),
     GNUNET_JSON_spec_timestamp ("validity_start",
                                 &start_time),
     GNUNET_JSON_spec_fixed_auto ("master_sig_add",
@@ -1577,7 +1577,6 @@ upload_wire_add (const char *exchange_url,
                 stderr,
                 JSON_INDENT (2));
     global_ret = EXIT_FAILURE;
-    GNUNET_JSON_parse_free (spec);
     test_shutdown ();
     return;
   }
@@ -1591,7 +1590,6 @@ upload_wire_add (const char *exchange_url,
                   "payto:// URI `%s' is malformed\n",
                   payto_uri);
       global_ret = EXIT_FAILURE;
-      GNUNET_JSON_parse_free (spec);
       test_shutdown ();
       return;
     }
@@ -1606,7 +1604,6 @@ upload_wire_add (const char *exchange_url,
                   "payto URI is malformed: %s\n",
                   msg);
       GNUNET_free (msg);
-      GNUNET_JSON_parse_free (spec);
       test_shutdown ();
       global_ret = EXIT_INVALIDARGUMENT;
       return;
@@ -1629,7 +1626,6 @@ upload_wire_add (const char *exchange_url,
   GNUNET_CONTAINER_DLL_insert (war_head,
                                war_tail,
                                war);
-  GNUNET_JSON_parse_free (spec);
 }
 
 
@@ -2102,13 +2098,13 @@ upload_keys (const char *exchange_url,
   struct UploadKeysRequest *ukr;
   const char *err_name;
   unsigned int err_line;
-  json_t *denom_sigs;
-  json_t *signkey_sigs;
+  const json_t *denom_sigs;
+  const json_t *signkey_sigs;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("denom_sigs",
-                           &denom_sigs),
-    GNUNET_JSON_spec_json ("signkey_sigs",
-                           &signkey_sigs),
+    GNUNET_JSON_spec_array_const ("denom_sigs",
+                                  &denom_sigs),
+    GNUNET_JSON_spec_array_const ("signkey_sigs",
+                                  &signkey_sigs),
     GNUNET_JSON_spec_end ()
   };
   bool ok = true;
@@ -2224,7 +2220,6 @@ upload_keys (const char *exchange_url,
   }
   GNUNET_free (pkd.sign_sigs);
   GNUNET_free (pkd.denom_sigs);
-  GNUNET_JSON_parse_free (spec);
 }
 
 
@@ -2272,13 +2267,13 @@ upload_extensions (const char *exchange_url,
                    size_t idx,
                    const json_t *value)
 {
-  json_t *extensions;
+  const json_t *extensions;
   struct TALER_MasterSignatureP sig;
   const char *err_name;
   unsigned int err_line;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("extensions",
-                           &extensions),
+    GNUNET_JSON_spec_object_const ("extensions",
+                                   &extensions),
     GNUNET_JSON_spec_fixed_auto ("extensions_sig",
                                  &sig),
     GNUNET_JSON_spec_end ()
@@ -2309,9 +2304,9 @@ upload_extensions (const char *exchange_url,
     struct TALER_ExtensionManifestsHashP h_manifests;
 
     if (GNUNET_OK !=
-        TALER_JSON_extensions_manifests_hash (extensions, &h_manifests))
+        TALER_JSON_extensions_manifests_hash (extensions,
+                                              &h_manifests))
     {
-      GNUNET_JSON_parse_free (spec);
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   "couldn't hash extensions' manifests\n");
       global_ret = EXIT_FAILURE;
@@ -2328,7 +2323,6 @@ upload_extensions (const char *exchange_url,
           &master_pub,
           &sig))
     {
-      GNUNET_JSON_parse_free (spec);
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   "invalid signature for extensions\n");
       global_ret = EXIT_FAILURE;
@@ -2343,8 +2337,9 @@ upload_extensions (const char *exchange_url,
       .extensions = extensions,
       .extensions_sig = sig,
     };
-    struct UploadExtensionsRequest *uer = GNUNET_new (struct
-                                                      UploadExtensionsRequest);
+    struct UploadExtensionsRequest *uer
+      = GNUNET_new (struct UploadExtensionsRequest);
+
     uer->idx = idx;
     uer->h = TALER_EXCHANGE_management_post_extensions (
       ctx,
@@ -2356,7 +2351,6 @@ upload_extensions (const char *exchange_url,
                                  uer_tail,
                                  uer);
   }
-  GNUNET_JSON_parse_free (spec);
 }
 
 
@@ -4482,15 +4476,15 @@ do_show (char *const *args)
   json_t *keys;
   const char *err_name;
   unsigned int err_line;
-  json_t *denomkeys;
-  json_t *signkeys;
+  const json_t *denomkeys;
+  const json_t *signkeys;
   struct TALER_MasterPublicKeyP mpub;
   struct TALER_SecurityModulePublicKeySetP secmset;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("future_denoms",
-                           &denomkeys),
-    GNUNET_JSON_spec_json ("future_signkeys",
-                           &signkeys),
+    GNUNET_JSON_spec_array_const ("future_denoms",
+                                  &denomkeys),
+    GNUNET_JSON_spec_array_const ("future_signkeys",
+                                  &signkeys),
     GNUNET_JSON_spec_fixed_auto ("master_pub",
                                  &mpub),
     GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
@@ -4535,7 +4529,6 @@ do_show (char *const *args)
                 "Fatal: exchange uses different master key!\n");
     global_ret = EXIT_FAILURE;
     test_shutdown ();
-    GNUNET_JSON_parse_free (spec);
     json_decref (keys);
     return;
   }
@@ -4544,7 +4537,6 @@ do_show (char *const *args)
   {
     global_ret = EXIT_FAILURE;
     test_shutdown ();
-    GNUNET_JSON_parse_free (spec);
     json_decref (keys);
     return;
   }
@@ -4558,12 +4550,10 @@ do_show (char *const *args)
   {
     global_ret = EXIT_FAILURE;
     test_shutdown ();
-    GNUNET_JSON_parse_free (spec);
     json_decref (keys);
     return;
   }
   json_decref (keys);
-  GNUNET_JSON_parse_free (spec);
   next (args);
 }
 
@@ -4883,15 +4873,15 @@ do_sign (char *const *args)
   json_t *keys;
   const char *err_name;
   unsigned int err_line;
-  json_t *denomkeys;
-  json_t *signkeys;
+  const json_t *denomkeys;
+  const json_t *signkeys;
   struct TALER_MasterPublicKeyP mpub;
   struct TALER_SecurityModulePublicKeySetP secmset;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("future_denoms",
-                           &denomkeys),
-    GNUNET_JSON_spec_json ("future_signkeys",
-                           &signkeys),
+    GNUNET_JSON_spec_array_const ("future_denoms",
+                                  &denomkeys),
+    GNUNET_JSON_spec_array_const ("future_signkeys",
+                                  &signkeys),
     GNUNET_JSON_spec_fixed_auto ("master_pub",
                                  &mpub),
     GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
@@ -4938,7 +4928,6 @@ do_sign (char *const *args)
                 "Fatal: exchange uses different master key!\n");
     global_ret = EXIT_FAILURE;
     test_shutdown ();
-    GNUNET_JSON_parse_free (spec);
     json_decref (keys);
     return;
   }
@@ -4949,7 +4938,6 @@ do_sign (char *const *args)
                 "Fatal: security module keys changed!\n");
     global_ret = EXIT_FAILURE;
     test_shutdown ();
-    GNUNET_JSON_parse_free (spec);
     json_decref (keys);
     return;
   }
@@ -4973,7 +4961,6 @@ do_sign (char *const *args)
       test_shutdown ();
       json_decref (signkey_sig_array);
       json_decref (denomkey_sig_array);
-      GNUNET_JSON_parse_free (spec);
       json_decref (keys);
       return;
     }
@@ -4985,7 +4972,6 @@ do_sign (char *const *args)
                         GNUNET_JSON_pack_array_steal ("signkey_sigs",
                                                       signkey_sig_array)));
   }
-  GNUNET_JSON_parse_free (spec);
   json_decref (keys);
   next (args);
 }
diff --git a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c 
b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c
index 776c0d8d..d604632d 100644
--- a/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c
+++ b/src/exchange/taler-exchange-httpd_age-withdraw_reveal.c
@@ -984,14 +984,18 @@ TEH_handler_age_withdraw_reveal (
   MHD_RESULT result = MHD_NO;
   enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR;
   struct AgeRevealContext actx = {0};
-  json_t *j_denoms_h;
-  json_t *j_coin_evs;
-  json_t *j_disclosed_coin_secrets;
+  const json_t *j_denoms_h;
+  const json_t *j_coin_evs;
+  const json_t *j_disclosed_coin_secrets;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_fixed_auto ("reserve_pub", &actx.reserve_pub),
-    GNUNET_JSON_spec_json ("denoms_h", &j_denoms_h),
-    GNUNET_JSON_spec_json ("coin_evs", &j_coin_evs),
-    GNUNET_JSON_spec_json ("disclosed_coin_secrets", 
&j_disclosed_coin_secrets),
+    GNUNET_JSON_spec_fixed_auto ("reserve_pub",
+                                 &actx.reserve_pub),
+    GNUNET_JSON_spec_array_const ("denoms_h",
+                                  &j_denoms_h),
+    GNUNET_JSON_spec_array_const ("coin_evs",
+                                  &j_coin_evs),
+    GNUNET_JSON_spec_array_const ("disclosed_coin_secrets",
+                                  &j_disclosed_coin_secrets),
     GNUNET_JSON_spec_end ()
   };
 
@@ -1010,7 +1014,8 @@ TEH_handler_age_withdraw_reveal (
 
   do {
     /* Extract denominations, blinded and disclosed coins */
-    if (GNUNET_OK != parse_age_withdraw_reveal_json (
+    if (GNUNET_OK !=
+        parse_age_withdraw_reveal_json (
           rc->connection,
           j_denoms_h,
           j_coin_evs,
@@ -1020,7 +1025,8 @@ TEH_handler_age_withdraw_reveal (
       break;
 
     /* Find original commitment */
-    if (GNUNET_OK != find_original_commitment (
+    if (GNUNET_OK !=
+        find_original_commitment (
           rc->connection,
           &actx.ach,
           &actx.reserve_pub,
@@ -1029,7 +1035,8 @@ TEH_handler_age_withdraw_reveal (
       break;
 
     /* Ensure validity of denoms and the sum of amounts and fees */
-    if (GNUNET_OK != are_denominations_valid (
+    if (GNUNET_OK !=
+        are_denominations_valid (
           rc->connection,
           actx.num_coins,
           actx.denoms_h,
@@ -1043,7 +1050,8 @@ TEH_handler_age_withdraw_reveal (
 
     /* Verify the computed h_commitment equals the committed one and that coins
      * have a maximum age group corresponding max_age (age-mask dependent) */
-    if (GNUNET_OK != verify_commitment_and_max_age (
+    if (GNUNET_OK !=
+        verify_commitment_and_max_age (
           rc->connection,
           &actx.commitment.h_commitment,
           actx.commitment.max_age,
@@ -1056,7 +1064,8 @@ TEH_handler_age_withdraw_reveal (
       break;
 
     /* Finally, sign and persist the coins */
-    if (GNUNET_OK != sign_and_finalize_age_withdraw (
+    if (GNUNET_OK !=
+        sign_and_finalize_age_withdraw (
           rc->connection,
           &actx.commitment.h_commitment,
           actx.num_coins,
@@ -1068,7 +1077,6 @@ TEH_handler_age_withdraw_reveal (
   } while(0);
 
   age_reveal_context_free (&actx);
-  GNUNET_JSON_parse_free (spec);
   return result;
 }
 
diff --git a/src/exchange/taler-exchange-httpd_aml-decision.c 
b/src/exchange/taler-exchange-httpd_aml-decision.c
index 2830e54e..c1439adc 100644
--- a/src/exchange/taler-exchange-httpd_aml-decision.c
+++ b/src/exchange/taler-exchange-httpd_aml-decision.c
@@ -74,7 +74,7 @@ struct DecisionContext
   /**
    * KYC requirements imposed, NULL for none.
    */
-  json_t *kyc_requirements;
+  const json_t *kyc_requirements;
 
 };
 
@@ -261,8 +261,8 @@ TEH_handler_post_aml_decision (
     GNUNET_JSON_spec_uint32 ("new_state",
                              &new_state32),
     GNUNET_JSON_spec_mark_optional (
-      GNUNET_JSON_spec_json ("kyc_requirements",
-                             &dc.kyc_requirements),
+      GNUNET_JSON_spec_array_const ("kyc_requirements",
+                                    &dc.kyc_requirements),
       NULL),
     GNUNET_JSON_spec_end ()
   };
@@ -306,17 +306,6 @@ TEH_handler_post_aml_decision (
     size_t index;
     json_t *elem;
 
-    if (! json_is_array (dc.kyc_requirements))
-    {
-      GNUNET_break_op (0);
-      GNUNET_JSON_parse_free (spec);
-      return TALER_MHD_reply_with_error (
-        connection,
-        MHD_HTTP_BAD_REQUEST,
-        TALER_EC_GENERIC_PARAMETER_MALFORMED,
-        "kyc_requirements must be an array");
-    }
-
     json_array_foreach (dc.kyc_requirements, index, elem)
     {
       const char *val;
@@ -324,7 +313,6 @@ TEH_handler_post_aml_decision (
       if (! json_is_string (elem))
       {
         GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
         return TALER_MHD_reply_with_error (
           connection,
           MHD_HTTP_BAD_REQUEST,
@@ -336,7 +324,6 @@ TEH_handler_post_aml_decision (
           TALER_KYCLOGIC_check_satisfiable (val))
       {
         GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
         return TALER_MHD_reply_with_error (
           connection,
           MHD_HTTP_BAD_REQUEST,
@@ -357,11 +344,9 @@ TEH_handler_post_aml_decision (
                                 &make_aml_decision,
                                 &dc))
     {
-      GNUNET_JSON_parse_free (spec);
       return mhd_ret;
     }
   }
-  GNUNET_JSON_parse_free (spec);
   return TALER_MHD_reply_static (
     connection,
     MHD_HTTP_NO_CONTENT,
diff --git a/src/exchange/taler-exchange-httpd_batch-deposit.c 
b/src/exchange/taler-exchange-httpd_batch-deposit.c
index d000c454..488f85ab 100644
--- a/src/exchange/taler-exchange-httpd_batch-deposit.c
+++ b/src/exchange/taler-exchange-httpd_batch-deposit.c
@@ -545,7 +545,7 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc,
 {
   struct MHD_Connection *connection = rc->connection;
   struct BatchDepositContext dc;
-  json_t *coins;
+  const json_t *coins;
   bool no_refund_deadline = true;
   bool no_policy_json = true;
   struct GNUNET_JSON_Specification spec[] = {
@@ -557,8 +557,8 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc,
                                  &dc.merchant_pub),
     GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
                                  &dc.h_contract_terms),
-    GNUNET_JSON_spec_json ("coins",
-                           &coins),
+    GNUNET_JSON_spec_array_const ("coins",
+                                  &coins),
     GNUNET_JSON_spec_mark_optional (
       GNUNET_JSON_spec_json ("policy",
                              &dc.policy_json),
diff --git a/src/exchange/taler-exchange-httpd_batch-withdraw.c 
b/src/exchange/taler-exchange-httpd_batch-withdraw.c
index c3065e1d..9d7d64cb 100644
--- a/src/exchange/taler-exchange-httpd_batch-withdraw.c
+++ b/src/exchange/taler-exchange-httpd_batch-withdraw.c
@@ -843,10 +843,10 @@ TEH_handler_batch_withdraw (struct TEH_RequestContext *rc,
     .reserve_pub = reserve_pub,
     .rc = rc
   };
-  json_t *planchets;
+  const json_t *planchets;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("planchets",
-                           &planchets),
+    GNUNET_JSON_spec_array_const ("planchets",
+                                  &planchets),
     GNUNET_JSON_spec_end ()
   };
 
@@ -862,20 +862,17 @@ TEH_handler_batch_withdraw (struct TEH_RequestContext *rc,
     if (GNUNET_OK != res)
       return (GNUNET_SYSERR == res) ? MHD_NO : MHD_YES;
   }
-  if ( (! json_is_array (planchets)) ||
-       (0 == json_array_size (planchets)) )
+  wc.planchets_length = json_array_size (planchets);
+  if (0 == wc.planchets_length)
   {
-    GNUNET_JSON_parse_free (spec);
     GNUNET_break_op (0);
     return TALER_MHD_reply_with_error (rc->connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
                                        "planchets");
   }
-  wc.planchets_length = json_array_size (planchets);
   if (wc.planchets_length > TALER_MAX_FRESH_COINS)
   {
-    GNUNET_JSON_parse_free (spec);
     GNUNET_break_op (0);
     return TALER_MHD_reply_with_error (rc->connection,
                                        MHD_HTTP_BAD_REQUEST,
@@ -901,7 +898,6 @@ TEH_handler_batch_withdraw (struct TEH_RequestContext *rc,
       TALER_blinded_planchet_free (&pc->blinded_planchet);
       TALER_blinded_denom_sig_free (&pc->collectable.sig);
     }
-    GNUNET_JSON_parse_free (spec);
     return ret;
   }
 }
diff --git a/src/exchange/taler-exchange-httpd_csr.c 
b/src/exchange/taler-exchange-httpd_csr.c
index 29f83c2c..3ceb319c 100644
--- a/src/exchange/taler-exchange-httpd_csr.c
+++ b/src/exchange/taler-exchange-httpd_csr.c
@@ -39,12 +39,12 @@ TEH_handler_csr_melt (struct TEH_RequestContext *rc,
 {
   struct TALER_RefreshMasterSecretP rms;
   unsigned int csr_requests_num;
-  json_t *csr_requests;
+  const json_t *csr_requests;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_fixed_auto ("rms",
                                  &rms),
-    GNUNET_JSON_spec_json ("nks",
-                           &csr_requests),
+    GNUNET_JSON_spec_array_const ("nks",
+                                  &csr_requests),
     GNUNET_JSON_spec_end ()
   };
   enum TALER_ErrorCode ec;
@@ -65,7 +65,7 @@ TEH_handler_csr_melt (struct TEH_RequestContext *rc,
   if ( (TALER_MAX_FRESH_COINS <= csr_requests_num) ||
        (0 == csr_requests_num) )
   {
-    GNUNET_JSON_parse_free (spec);
+    GNUNET_break_op (0);
     return TALER_MHD_reply_with_error (
       rc->connection,
       MHD_HTTP_BAD_REQUEST,
@@ -101,14 +101,12 @@ TEH_handler_csr_melt (struct TEH_RequestContext *rc,
                                           -1);
         if (GNUNET_OK != res)
         {
-          GNUNET_JSON_parse_free (spec);
           return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
         }
         TALER_cs_refresh_nonce_derive (&rms,
                                        coin_off,
                                        &nonces[i]);
       }
-      GNUNET_JSON_parse_free (spec);
 
       for (unsigned int i = 0; i < csr_requests_num; i++)
       {
diff --git a/src/exchange/taler-exchange-httpd_management_extensions.c 
b/src/exchange/taler-exchange-httpd_management_extensions.c
index d5841a3c..3b24bace 100644
--- a/src/exchange/taler-exchange-httpd_management_extensions.c
+++ b/src/exchange/taler-exchange-httpd_management_extensions.c
@@ -145,7 +145,7 @@ set_extensions (void *cls,
 
 static enum GNUNET_GenericReturnValue
 verify_extensions_from_json (
-  json_t *extensions,
+  const json_t *extensions,
   struct SetExtensionsContext *sec)
 {
   const char*name;
@@ -160,7 +160,7 @@ verify_extensions_from_json (
   sec->extensions = GNUNET_new_array (sec->num_extensions,
                                       struct Extension);
 
-  json_object_foreach (extensions, name, manifest)
+  json_object_foreach ((json_t *) extensions, name, manifest)
   {
     int critical = 0;
     json_t *config;
@@ -200,11 +200,11 @@ TEH_handler_management_post_extensions (
   const json_t *root)
 {
   MHD_RESULT ret;
-  json_t *extensions;
+  const json_t *extensions;
   struct SetExtensionsContext sec = {0};
   struct GNUNET_JSON_Specification top_spec[] = {
-    GNUNET_JSON_spec_json ("extensions",
-                           &extensions),
+    GNUNET_JSON_spec_object_const ("extensions",
+                                   &extensions),
     GNUNET_JSON_spec_fixed_auto ("extensions_sig",
                                  &sec.extensions_sig),
     GNUNET_JSON_spec_end ()
@@ -223,31 +223,19 @@ TEH_handler_management_post_extensions (
       return MHD_YES; /* failure */
   }
 
-  /* Ensure we have an object */
-  if ((! json_is_object (extensions)) &&
-      (! json_is_null (extensions)))
-  {
-    GNUNET_JSON_parse_free (top_spec);
-    return TALER_MHD_reply_with_error (
-      connection,
-      MHD_HTTP_BAD_REQUEST,
-      TALER_EC_GENERIC_PARAMETER_MALFORMED,
-      "invalid object");
-  }
-
   /* Verify the signature */
   {
     struct TALER_ExtensionManifestsHashP h_manifests;
 
     if (GNUNET_OK !=
-        TALER_JSON_extensions_manifests_hash (extensions, &h_manifests) ||
+        TALER_JSON_extensions_manifests_hash (extensions,
+                                              &h_manifests) ||
         GNUNET_OK !=
         TALER_exchange_offline_extension_manifests_hash_verify (
           &h_manifests,
           &TEH_master_public_key,
           &sec.extensions_sig))
     {
-      GNUNET_JSON_parse_free (top_spec);
       return TALER_MHD_reply_with_error (
         connection,
         MHD_HTTP_BAD_REQUEST,
@@ -263,7 +251,6 @@ TEH_handler_management_post_extensions (
   if (GNUNET_OK !=
       verify_extensions_from_json (extensions, &sec))
   {
-    GNUNET_JSON_parse_free (top_spec);
     return TALER_MHD_reply_with_error (
       connection,
       MHD_HTTP_BAD_REQUEST,
@@ -306,7 +293,6 @@ CLEANUP:
     }
   }
   GNUNET_free (sec.extensions);
-  GNUNET_JSON_parse_free (top_spec);
   return ret;
 }
 
diff --git a/src/exchange/taler-exchange-httpd_management_post_keys.c 
b/src/exchange/taler-exchange-httpd_management_post_keys.c
index df351ad5..0ddc4691 100644
--- a/src/exchange/taler-exchange-httpd_management_post_keys.c
+++ b/src/exchange/taler-exchange-httpd_management_post_keys.c
@@ -340,13 +340,13 @@ TEH_handler_management_post_keys (
   const json_t *root)
 {
   struct AddKeysContext akc;
-  json_t *denom_sigs;
-  json_t *signkey_sigs;
+  const json_t *denom_sigs;
+  const json_t *signkey_sigs;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("denom_sigs",
-                           &denom_sigs),
-    GNUNET_JSON_spec_json ("signkey_sigs",
-                           &signkey_sigs),
+    GNUNET_JSON_spec_array_const ("denom_sigs",
+                                  &denom_sigs),
+    GNUNET_JSON_spec_array_const ("signkey_sigs",
+                                  &signkey_sigs),
     GNUNET_JSON_spec_end ()
   };
   bool ok;
@@ -363,24 +363,12 @@ TEH_handler_management_post_keys (
     if (GNUNET_NO == res)
       return MHD_YES; /* failure */
   }
-  if (! (json_is_array (denom_sigs) &&
-         json_is_array (signkey_sigs)) )
-  {
-    GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
-    return TALER_MHD_reply_with_error (
-      connection,
-      MHD_HTTP_BAD_REQUEST,
-      TALER_EC_GENERIC_PARAMETER_MALFORMED,
-      "array expected for denom_sigs and signkey_sigs");
-  }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               "Received /management/keys\n");
   akc.ksh = TEH_keys_get_state_for_management_only (); /* may start its own 
transaction, thus must be done here, before we run ours! */
   if (NULL == akc.ksh)
   {
     GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
     return TALER_MHD_reply_with_error (
       connection,
       MHD_HTTP_INTERNAL_SERVER_ERROR,
@@ -423,7 +411,6 @@ TEH_handler_management_post_keys (
   if (! ok)
   {
     GNUNET_free (akc.d_sigs);
-    GNUNET_JSON_parse_free (spec);
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Failure to handle /management/keys\n");
     return ret;
@@ -466,7 +453,6 @@ TEH_handler_management_post_keys (
                 "Failure to handle /management/keys\n");
     GNUNET_free (akc.d_sigs);
     GNUNET_free (akc.s_sigs);
-    GNUNET_JSON_parse_free (spec);
     return ret;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -484,7 +470,6 @@ TEH_handler_management_post_keys (
                                   &akc);
     GNUNET_free (akc.d_sigs);
     GNUNET_free (akc.s_sigs);
-    GNUNET_JSON_parse_free (spec);
     if (GNUNET_SYSERR == res)
       return ret;
   }
diff --git a/src/exchange/taler-exchange-httpd_management_wire_enable.c 
b/src/exchange/taler-exchange-httpd_management_wire_enable.c
index 6743b485..a67d1ad6 100644
--- a/src/exchange/taler-exchange-httpd_management_wire_enable.c
+++ b/src/exchange/taler-exchange-httpd_management_wire_enable.c
@@ -62,12 +62,12 @@ struct AddWireContext
   /**
    * Restrictions imposed when crediting this account.
    */
-  json_t *credit_restrictions;
+  const json_t *credit_restrictions;
 
   /**
    * Restrictions imposed when debiting this account.
    */
-  json_t *debit_restrictions;
+  const json_t *debit_restrictions;
 
   /**
    * Timestamp for checking against replay attacks.
@@ -176,10 +176,10 @@ TEH_handler_management_post_wire (
       GNUNET_JSON_spec_string ("conversion_url",
                                &awc.conversion_url),
       NULL),
-    GNUNET_JSON_spec_json ("credit_restrictions",
-                           &awc.credit_restrictions),
-    GNUNET_JSON_spec_json ("debit_restrictions",
-                           &awc.debit_restrictions),
+    GNUNET_JSON_spec_array_const ("credit_restrictions",
+                                  &awc.credit_restrictions),
+    GNUNET_JSON_spec_array_const ("debit_restrictions",
+                                  &awc.debit_restrictions),
     GNUNET_JSON_spec_timestamp ("validity_start",
                                 &awc.validity_start),
     GNUNET_JSON_spec_end ()
diff --git a/src/exchange/taler-exchange-httpd_purses_create.c 
b/src/exchange/taler-exchange-httpd_purses_create.c
index 130f9fae..2de9468f 100644
--- a/src/exchange/taler-exchange-httpd_purses_create.c
+++ b/src/exchange/taler-exchange-httpd_purses_create.c
@@ -430,7 +430,7 @@ TEH_handler_purses_create (
     .pd.purse_pub = *purse_pub,
     .exchange_timestamp = GNUNET_TIME_timestamp_get ()
   };
-  json_t *deposits;
+  const json_t *deposits;
   json_t *deposit;
   unsigned int idx;
   struct GNUNET_JSON_Specification spec[] = {
@@ -449,8 +449,8 @@ TEH_handler_purses_create (
                                  &pcc.purse_sig),
     GNUNET_JSON_spec_fixed_auto ("h_contract_terms",
                                  &pcc.pd.h_contract_terms),
-    GNUNET_JSON_spec_json ("deposits",
-                           &deposits),
+    GNUNET_JSON_spec_array_const ("deposits",
+                                  &deposits),
     GNUNET_JSON_spec_timestamp ("purse_expiration",
                                 &pcc.pd.purse_expiration),
     GNUNET_JSON_spec_end ()
@@ -482,7 +482,6 @@ TEH_handler_purses_create (
                                  pcc.exchange_timestamp))
   {
     GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        
TALER_EC_EXCHANGE_PURSE_CREATE_EXPIRATION_BEFORE_NOW,
@@ -491,7 +490,6 @@ TEH_handler_purses_create (
   if (GNUNET_TIME_absolute_is_never (pcc.pd.purse_expiration.abs_time))
   {
     GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        
TALER_EC_EXCHANGE_PURSE_CREATE_EXPIRATION_IS_NEVER,
@@ -502,7 +500,6 @@ TEH_handler_purses_create (
        (pcc.num_coins > TALER_MAX_FRESH_COINS) )
   {
     GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
@@ -515,7 +512,6 @@ TEH_handler_purses_create (
     if (NULL == keys)
     {
       GNUNET_break (0);
-      GNUNET_JSON_parse_free (spec);
       return TALER_MHD_reply_with_error (connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
                                          
TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING,
@@ -547,7 +543,6 @@ TEH_handler_purses_create (
                       deposit);
     if (GNUNET_OK != res)
     {
-      GNUNET_JSON_parse_free (spec);
       for (unsigned int i = 0; i<idx; i++)
         TEH_common_purse_deposit_free_coin (&pcc.coins[i]);
       GNUNET_free (pcc.coins);
@@ -559,7 +554,6 @@ TEH_handler_purses_create (
                             &pcc.deposit_total))
   {
     GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
     GNUNET_free (pcc.coins);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
@@ -579,7 +573,6 @@ TEH_handler_purses_create (
         &pcc.purse_sig))
   {
     TALER_LOG_WARNING ("Invalid signature on /purses/$PID/create request\n");
-    GNUNET_JSON_parse_free (spec);
     for (unsigned int i = 0; i<pcc.num_coins; i++)
       TEH_common_purse_deposit_free_coin (&pcc.coins[i]);
     GNUNET_free (pcc.coins);
@@ -597,7 +590,6 @@ TEH_handler_purses_create (
                                               &pcc.econtract.econtract_sig)) )
   {
     TALER_LOG_WARNING ("Invalid signature on /purses/$PID/create request\n");
-    GNUNET_JSON_parse_free (spec);
     for (unsigned int i = 0; i<pcc.num_coins; i++)
       TEH_common_purse_deposit_free_coin (&pcc.coins[i]);
     GNUNET_free (pcc.coins);
@@ -612,7 +604,6 @@ TEH_handler_purses_create (
       TEH_plugin->preflight (TEH_plugin->cls))
   {
     GNUNET_break (0);
-    GNUNET_JSON_parse_free (spec);
     for (unsigned int i = 0; i<pcc.num_coins; i++)
       TEH_common_purse_deposit_free_coin (&pcc.coins[i]);
     GNUNET_free (pcc.coins);
@@ -634,7 +625,6 @@ TEH_handler_purses_create (
                                 &create_transaction,
                                 &pcc))
     {
-      GNUNET_JSON_parse_free (spec);
       for (unsigned int i = 0; i<pcc.num_coins; i++)
         TEH_common_purse_deposit_free_coin (&pcc.coins[i]);
       GNUNET_free (pcc.coins);
@@ -653,7 +643,6 @@ TEH_handler_purses_create (
     for (unsigned int i = 0; i<pcc.num_coins; i++)
       TEH_common_purse_deposit_free_coin (&pcc.coins[i]);
     GNUNET_free (pcc.coins);
-    GNUNET_JSON_parse_free (spec);
     return res;
   }
 }
diff --git a/src/exchange/taler-exchange-httpd_purses_deposit.c 
b/src/exchange/taler-exchange-httpd_purses_deposit.c
index 291807aa..973dfccf 100644
--- a/src/exchange/taler-exchange-httpd_purses_deposit.c
+++ b/src/exchange/taler-exchange-httpd_purses_deposit.c
@@ -329,12 +329,12 @@ TEH_handler_purses_deposit (
     .purse_pub = purse_pub,
     .exchange_timestamp = GNUNET_TIME_timestamp_get ()
   };
-  json_t *deposits;
+  const json_t *deposits;
   json_t *deposit;
   unsigned int idx;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("deposits",
-                           &deposits),
+    GNUNET_JSON_spec_array_const ("deposits",
+                                  &deposits),
     GNUNET_JSON_spec_end ()
   };
 
@@ -363,7 +363,6 @@ TEH_handler_purses_deposit (
        (pcc.num_coins > TALER_MAX_FRESH_COINS) )
   {
     GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
     return TALER_MHD_reply_with_error (connection,
                                        MHD_HTTP_BAD_REQUEST,
                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
@@ -435,7 +434,6 @@ TEH_handler_purses_deposit (
                       deposit);
     if (GNUNET_OK != res)
     {
-      GNUNET_JSON_parse_free (spec);
       for (unsigned int i = 0; i<idx; i++)
         TEH_common_purse_deposit_free_coin (&pcc.coins[i]);
       GNUNET_free (pcc.coins);
@@ -447,7 +445,6 @@ TEH_handler_purses_deposit (
       TEH_plugin->preflight (TEH_plugin->cls))
   {
     GNUNET_break (0);
-    GNUNET_JSON_parse_free (spec);
     for (unsigned int i = 0; i<pcc.num_coins; i++)
       TEH_common_purse_deposit_free_coin (&pcc.coins[i]);
     GNUNET_free (pcc.coins);
@@ -469,7 +466,6 @@ TEH_handler_purses_deposit (
                                 &deposit_transaction,
                                 &pcc))
     {
-      GNUNET_JSON_parse_free (spec);
       for (unsigned int i = 0; i<pcc.num_coins; i++)
         TEH_common_purse_deposit_free_coin (&pcc.coins[i]);
       GNUNET_free (pcc.coins);
@@ -501,7 +497,6 @@ TEH_handler_purses_deposit (
     for (unsigned int i = 0; i<pcc.num_coins; i++)
       TEH_common_purse_deposit_free_coin (&pcc.coins[i]);
     GNUNET_free (pcc.coins);
-    GNUNET_JSON_parse_free (spec);
     return res;
   }
 }
diff --git a/src/exchange/taler-exchange-httpd_refreshes_reveal.c 
b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
index 89bdf272..47926a74 100644
--- a/src/exchange/taler-exchange-httpd_refreshes_reveal.c
+++ b/src/exchange/taler-exchange-httpd_refreshes_reveal.c
@@ -983,26 +983,26 @@ TEH_handler_reveal (struct TEH_RequestContext *rc,
                     const json_t *root,
                     const char *const args[2])
 {
-  json_t *coin_evs;
-  json_t *transfer_privs;
-  json_t *link_sigs;
-  json_t *new_denoms_h;
-  json_t *old_age_commitment;
+  const json_t *coin_evs;
+  const json_t *transfer_privs;
+  const json_t *link_sigs;
+  const json_t *new_denoms_h;
+  const json_t *old_age_commitment;
   struct RevealContext rctx;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_fixed_auto ("transfer_pub",
                                  &rctx.gamma_tp),
-    GNUNET_JSON_spec_json ("transfer_privs",
-                           &transfer_privs),
-    GNUNET_JSON_spec_json ("link_sigs",
-                           &link_sigs),
-    GNUNET_JSON_spec_json ("coin_evs",
-                           &coin_evs),
-    GNUNET_JSON_spec_json ("new_denoms_h",
-                           &new_denoms_h),
+    GNUNET_JSON_spec_array_const ("transfer_privs",
+                                  &transfer_privs),
+    GNUNET_JSON_spec_array_const ("link_sigs",
+                                  &link_sigs),
+    GNUNET_JSON_spec_array_const ("coin_evs",
+                                  &coin_evs),
+    GNUNET_JSON_spec_array_const ("new_denoms_h",
+                                  &new_denoms_h),
     GNUNET_JSON_spec_mark_optional (
-      GNUNET_JSON_spec_json ("old_age_commitment",
-                             &old_age_commitment),
+      GNUNET_JSON_spec_array_const ("old_age_commitment",
+                                    &old_age_commitment),
       NULL),
     GNUNET_JSON_spec_mark_optional (
       GNUNET_JSON_spec_fixed_auto ("rms",
@@ -1053,7 +1053,6 @@ TEH_handler_reveal (struct TEH_RequestContext *rc,
   /* Note we do +1 as 1 row (cut-and-choose!) is missing! */
   if (TALER_CNC_KAPPA != json_array_size (transfer_privs) + 1)
   {
-    GNUNET_JSON_parse_free (spec);
     GNUNET_break_op (0);
     return TALER_MHD_reply_with_error (rc->connection,
                                        MHD_HTTP_BAD_REQUEST,
@@ -1061,19 +1060,13 @@ TEH_handler_reveal (struct TEH_RequestContext *rc,
                                        NULL);
   }
 
-  {
-    MHD_RESULT res;
-
-    res = handle_refreshes_reveal_json (rc->connection,
-                                        &rctx,
-                                        transfer_privs,
-                                        link_sigs,
-                                        new_denoms_h,
-                                        old_age_commitment,
-                                        coin_evs);
-    GNUNET_JSON_parse_free (spec);
-    return res;
-  }
+  return handle_refreshes_reveal_json (rc->connection,
+                                       &rctx,
+                                       transfer_privs,
+                                       link_sigs,
+                                       new_denoms_h,
+                                       old_age_commitment,
+                                       coin_evs);
 }
 
 
diff --git a/src/exchange/taler-exchange-httpd_reserves_attest.c 
b/src/exchange/taler-exchange-httpd_reserves_attest.c
index d0f3614e..7bbebaad 100644
--- a/src/exchange/taler-exchange-httpd_reserves_attest.c
+++ b/src/exchange/taler-exchange-httpd_reserves_attest.c
@@ -68,7 +68,7 @@ struct ReserveAttestContext
   /**
    * List of requested details.
    */
-  json_t *details;
+  const json_t *details;
 
   /**
    * Client signature approving the request.
@@ -287,8 +287,8 @@ TEH_handler_reserves_attest (struct TEH_RequestContext *rc,
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_timestamp ("request_timestamp",
                                 &rsc.timestamp),
-    GNUNET_JSON_spec_json ("details",
-                           &rsc.details),
+    GNUNET_JSON_spec_array_const ("details",
+                                  &rsc.details),
     GNUNET_JSON_spec_fixed_auto ("reserve_sig",
                                  &rsc.reserve_sig),
     GNUNET_JSON_spec_end ()
diff --git a/src/exchange/taler-exchange-httpd_reserves_open.c 
b/src/exchange/taler-exchange-httpd_reserves_open.c
index 6909c862..50487990 100644
--- a/src/exchange/taler-exchange-httpd_reserves_open.c
+++ b/src/exchange/taler-exchange-httpd_reserves_open.c
@@ -303,7 +303,7 @@ TEH_handler_reserves_open (struct TEH_RequestContext *rc,
                            const json_t *root)
 {
   struct ReserveOpenContext rsc;
-  json_t *payments;
+  const json_t *payments;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_timestamp ("request_timestamp",
                                 &rsc.timestamp),
@@ -313,8 +313,8 @@ TEH_handler_reserves_open (struct TEH_RequestContext *rc,
                                  &rsc.reserve_sig),
     GNUNET_JSON_spec_uint32 ("purse_limit",
                              &rsc.purse_limit),
-    GNUNET_JSON_spec_json ("payments",
-                           &payments),
+    GNUNET_JSON_spec_array_const ("payments",
+                                  &payments),
     TALER_JSON_spec_amount ("reserve_payment",
                             TEH_currency,
                             &rsc.reserve_payment),
@@ -403,7 +403,6 @@ TEH_handler_reserves_open (struct TEH_RequestContext *rc,
     if (NULL == keys)
     {
       GNUNET_break (0);
-      GNUNET_JSON_parse_free (spec);
       cleanup_rsc (&rsc);
       return TALER_MHD_reply_with_error (rc->connection,
                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
diff --git a/src/exchangedb/pg_insert_wire.c b/src/exchangedb/pg_insert_wire.c
index 8329a04a..066143b9 100644
--- a/src/exchangedb/pg_insert_wire.c
+++ b/src/exchangedb/pg_insert_wire.c
@@ -30,8 +30,8 @@ enum GNUNET_DB_QueryStatus
 TEH_PG_insert_wire (void *cls,
                     const char *payto_uri,
                     const char *conversion_url,
-                    json_t *debit_restrictions,
-                    json_t *credit_restrictions,
+                    const json_t *debit_restrictions,
+                    const json_t *credit_restrictions,
                     struct GNUNET_TIME_Timestamp start_date,
                     const struct TALER_MasterSignatureP *master_sig)
 {
diff --git a/src/exchangedb/pg_insert_wire.h b/src/exchangedb/pg_insert_wire.h
index c949327d..35894671 100644
--- a/src/exchangedb/pg_insert_wire.h
+++ b/src/exchangedb/pg_insert_wire.h
@@ -42,8 +42,8 @@ enum GNUNET_DB_QueryStatus
 TEH_PG_insert_wire (void *cls,
                     const char *payto_uri,
                     const char *conversion_url,
-                    json_t *debit_restrictions,
-                    json_t *credit_restrictions,
+                    const json_t *debit_restrictions,
+                    const json_t *credit_restrictions,
                     struct GNUNET_TIME_Timestamp start_date,
                     const struct TALER_MasterSignatureP *master_sig);
 
diff --git a/src/exchangedb/pg_update_wire.c b/src/exchangedb/pg_update_wire.c
index 0c4ec7b5..f3b07468 100644
--- a/src/exchangedb/pg_update_wire.c
+++ b/src/exchangedb/pg_update_wire.c
@@ -30,8 +30,8 @@ enum GNUNET_DB_QueryStatus
 TEH_PG_update_wire (void *cls,
                     const char *payto_uri,
                     const char *conversion_url,
-                    json_t *debit_restrictions,
-                    json_t *credit_restrictions,
+                    const json_t *debit_restrictions,
+                    const json_t *credit_restrictions,
                     struct GNUNET_TIME_Timestamp change_date,
                     bool enabled)
 {
diff --git a/src/exchangedb/pg_update_wire.h b/src/exchangedb/pg_update_wire.h
index 360b8845..ecdbc405 100644
--- a/src/exchangedb/pg_update_wire.h
+++ b/src/exchangedb/pg_update_wire.h
@@ -43,8 +43,8 @@ enum GNUNET_DB_QueryStatus
 TEH_PG_update_wire (void *cls,
                     const char *payto_uri,
                     const char *conversion_url,
-                    json_t *debit_restrictions,
-                    json_t *credit_restrictions,
+                    const json_t *debit_restrictions,
+                    const json_t *credit_restrictions,
                     struct GNUNET_TIME_Timestamp change_date,
                     bool enabled);
 
diff --git a/src/extensions/extensions.c b/src/extensions/extensions.c
index fc361e08..731ccfd0 100644
--- a/src/extensions/extensions.c
+++ b/src/extensions/extensions.c
@@ -138,7 +138,7 @@ TALER_extensions_get_by_name (
 
 enum GNUNET_GenericReturnValue
 TALER_extensions_verify_manifests_signature (
-  json_t *manifests,
+  const json_t *manifests,
   struct TALER_MasterSignatureP *extensions_sig,
   struct TALER_MasterPublicKeyP *master_pub)
 {
@@ -274,72 +274,76 @@ TALER_extensions_parse_manifest (
   json_t **config)
 {
   enum GNUNET_GenericReturnValue ret;
-  json_t *cfg;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_boolean ("critical",
                               critical),
     GNUNET_JSON_spec_string ("version",
                              version),
     GNUNET_JSON_spec_json ("config",
-                           &cfg),
+                           config),
     GNUNET_JSON_spec_end ()
   };
 
+  *config = NULL;
   if (GNUNET_OK !=
       (ret = GNUNET_JSON_parse (obj,
                                 spec,
                                 NULL,
                                 NULL)))
     return ret;
-
-  *config = json_copy (cfg);
-  GNUNET_JSON_parse_free (spec);
-
   return GNUNET_OK;
 }
 
 
 enum GNUNET_GenericReturnValue
 TALER_extensions_load_manifests (
-  json_t *extensions)
+  const json_t *extensions)
 {
-  const char*name;
+  const char *name;
   json_t *manifest;
 
   GNUNET_assert (NULL != extensions);
   GNUNET_assert (json_is_object (extensions));
 
-  json_object_foreach (extensions, name, manifest)
+  json_object_foreach ((json_t *) extensions, name, manifest)
   {
     int critical;
     const char *version;
     json_t *config;
-    struct TALER_Extension *extension =  (struct
-                                          TALER_Extension *)
-                                        TALER_extensions_get_by_name (name);
+    struct TALER_Extension *extension
+      = (struct TALER_Extension *)
+        TALER_extensions_get_by_name (name);
 
     if (NULL == extension)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "no such extension: %s\n", name);
+                  "no such extension: %s\n",
+                  name);
       return GNUNET_SYSERR;
     }
 
     /* load and verify criticality, version, etc. */
     if (GNUNET_OK !=
         TALER_extensions_parse_manifest (
-          manifest, &critical, &version, &config))
+          manifest,
+          &critical,
+          &version,
+          &config))
       return GNUNET_SYSERR;
 
     if (critical != extension->critical
-        || 0 != strcmp (version, extension->version) // TODO: libtool compare?
+        || 0 != strcmp (version,
+                        extension->version) // TODO: libtool compare?
         || NULL == config
-        || GNUNET_OK != extension->load_config (config, NULL))
+        || (GNUNET_OK !=
+            extension->load_config (config,
+                                    NULL)) )
       return GNUNET_SYSERR;
 
     /* This _should_ work now */
     if (GNUNET_OK !=
-        extension->load_config (config, extension))
+        extension->load_config (config,
+                                extension))
       return GNUNET_SYSERR;
 
     extension->enabled = true;
diff --git a/src/include/taler_exchange_service.h 
b/src/include/taler_exchange_service.h
index 6d4ca109..5fcfa403 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -3592,7 +3592,7 @@ enum GNUNET_GenericReturnValue
 TALER_EXCHANGE_verify_coin_history (
   const struct TALER_EXCHANGE_DenomPublicKey *dk,
   const struct TALER_CoinSpendPublicKeyP *coin_pub,
-  json_t *history,
+  const json_t *history,
   struct TALER_Amount *total);
 
 
@@ -4498,7 +4498,7 @@ TALER_EXCHANGE_post_management_keys_cancel (
  */
 struct TALER_EXCHANGE_ManagementPostExtensionsData
 {
-  json_t *extensions;
+  const json_t *extensions;
   struct TALER_MasterSignatureP extensions_sig;
 };
 
diff --git a/src/include/taler_exchangedb_plugin.h 
b/src/include/taler_exchangedb_plugin.h
index 92fb36fb..5404f0b1 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -5577,8 +5577,8 @@ struct TALER_EXCHANGEDB_Plugin
   (*insert_wire)(void *cls,
                  const char *payto_uri,
                  const char *conversion_url,
-                 json_t *debit_restrictions,
-                 json_t *credit_restrictions,
+                 const json_t *debit_restrictions,
+                 const json_t *credit_restrictions,
                  struct GNUNET_TIME_Timestamp start_date,
                  const struct TALER_MasterSignatureP *master_sig);
 
@@ -5600,8 +5600,8 @@ struct TALER_EXCHANGEDB_Plugin
   (*update_wire)(void *cls,
                  const char *payto_uri,
                  const char *conversion_url,
-                 json_t *debit_restrictions,
-                 json_t *credit_restrictions,
+                 const json_t *debit_restrictions,
+                 const json_t *credit_restrictions,
                  struct GNUNET_TIME_Timestamp change_date,
                  bool enabled);
 
diff --git a/src/include/taler_extensions.h b/src/include/taler_extensions.h
index 75f22534..cd9d7ddd 100644
--- a/src/include/taler_extensions.h
+++ b/src/include/taler_extensions.h
@@ -259,13 +259,13 @@ TALER_extensions_parse_manifest (
  */
 enum GNUNET_GenericReturnValue
 TALER_extensions_load_manifests (
-  json_t *manifests);
+  const json_t *manifests);
 
 /*
  * @brief Returns the head of the linked list of extensions.
  */
 const struct TALER_Extensions *
-TALER_extensions_get_head ();
+TALER_extensions_get_head (void);
 
 /**
  * @brief Finds and returns a supported extension by a given type.
@@ -323,7 +323,7 @@ TALER_extensions_is_enabled (
  */
 enum GNUNET_GenericReturnValue
 TALER_extensions_verify_manifests_signature (
-  json_t *manifests,
+  const json_t *manifests,
   struct TALER_MasterSignatureP *extensions_sig,
   struct TALER_MasterPublicKeyP *master_pub);
 
@@ -363,7 +363,7 @@ struct TALER_AgeRestrictionConfig
  * @return age restriction configuration if present, otherwise NULL.
  */
 const struct TALER_AgeRestrictionConfig *
-TALER_extensions_get_age_restriction_config ();
+TALER_extensions_get_age_restriction_config (void);
 
 /**
  * @brief Check if age restriction is enabled
@@ -371,7 +371,7 @@ TALER_extensions_get_age_restriction_config ();
  * @return true, if age restriction is loaded, configured and enabled; 
otherwise false.
  */
 bool
-TALER_extensions_is_age_restriction_enabled ();
+TALER_extensions_is_age_restriction_enabled (void);
 
 /**
  * @brief Return the age mask for age restriction
@@ -379,6 +379,6 @@ TALER_extensions_is_age_restriction_enabled ();
  * @return configured age mask, if age restriction is loaded, configured and 
enabled; otherwise zero mask.
  */
 struct TALER_AgeMask
-TALER_extensions_get_age_restriction_mask ();
+TALER_extensions_get_age_restriction_mask (void);
 
 #endif
diff --git a/src/kyclogic/plugin_kyclogic_kycaid.c 
b/src/kyclogic/plugin_kyclogic_kycaid.c
index 95dc4bb7..058c41e1 100644
--- a/src/kyclogic/plugin_kyclogic_kycaid.c
+++ b/src/kyclogic/plugin_kyclogic_kycaid.c
@@ -758,11 +758,12 @@ kycaid_webhook_cancel (struct 
TALER_KYCLOGIC_WebhookHandle *wh)
  * @param verifications JSON object with failure details
  */
 static void
-log_failure (json_t *verifications)
+log_failure (const json_t *verifications)
 {
-  json_t *member;
+  const json_t *member;
   const char *name;
-  json_object_foreach (verifications, name, member)
+
+  json_object_foreach ((json_t *) verifications, name, member)
   {
     bool iverified;
     const char *comment;
@@ -1176,7 +1177,7 @@ kycaid_webhook (void *cls,
   const char *status = NULL;
   bool verified = false;
   bool no_verified = true;
-  json_t *verifications = NULL;
+  const json_t *verifications = NULL;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_string ("request_id",
                              &request_id),
@@ -1195,8 +1196,8 @@ kycaid_webhook (void *cls,
                              &verified),
       &no_verified),
     GNUNET_JSON_spec_mark_optional (
-      GNUNET_JSON_spec_json ("verifications",
-                             &verifications),
+      GNUNET_JSON_spec_object_const ("verifications",
+                                     &verifications),
       NULL),
     GNUNET_JSON_spec_end ()
   };
@@ -1253,7 +1254,6 @@ kycaid_webhook (void *cls,
     wh->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
     wh->task = GNUNET_SCHEDULER_add_now (&async_webhook_reply,
                                          wh);
-    GNUNET_JSON_parse_free (spec);
     return wh;
   }
   if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
@@ -1267,7 +1267,6 @@ kycaid_webhook (void *cls,
     wh->response_code = MHD_HTTP_NOT_FOUND;
     wh->task = GNUNET_SCHEDULER_add_now (&async_webhook_reply,
                                          wh);
-    GNUNET_JSON_parse_free (spec);
     return wh;
   }
   wh->verification_id = GNUNET_strdup (verification_id);
@@ -1286,7 +1285,6 @@ kycaid_webhook (void *cls,
                                                 MHD_RESPMEM_PERSISTENT);
     wh->task = GNUNET_SCHEDULER_add_now (&async_webhook_reply,
                                          wh);
-    GNUNET_JSON_parse_free (spec);
     return wh;
   }
 
@@ -1300,7 +1298,6 @@ kycaid_webhook (void *cls,
     wh->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
     wh->task = GNUNET_SCHEDULER_add_now (&async_webhook_reply,
                                          wh);
-    GNUNET_JSON_parse_free (spec);
     return wh;
   }
 
@@ -1324,7 +1321,6 @@ kycaid_webhook (void *cls,
                                   pd->slist,
                                   &handle_webhook_finished,
                                   wh);
-  GNUNET_JSON_parse_free (spec);
   return wh;
 }
 
diff --git a/src/kyclogic/plugin_kyclogic_oauth2.c 
b/src/kyclogic/plugin_kyclogic_oauth2.c
index e7350f01..c9e5d8dc 100644
--- a/src/kyclogic/plugin_kyclogic_oauth2.c
+++ b/src/kyclogic/plugin_kyclogic_oauth2.c
@@ -951,12 +951,12 @@ parse_proof_success_reply (struct 
TALER_KYCLOGIC_ProofHandle *ph,
                            const json_t *j)
 {
   const char *state;
-  json_t *data;
+  const json_t *data;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_string ("status",
                              &state),
-    GNUNET_JSON_spec_json ("data",
-                           &data),
+    GNUNET_JSON_spec_object_const ("data",
+                                   &data),
     GNUNET_JSON_spec_end ()
   };
   enum GNUNET_GenericReturnValue res;
@@ -988,7 +988,6 @@ parse_proof_success_reply (struct 
TALER_KYCLOGIC_ProofHandle *ph,
     GNUNET_break_op (0);
     handle_proof_error (ph,
                         j);
-    GNUNET_JSON_parse_free (spec);
     return;
   }
   {
@@ -1016,7 +1015,6 @@ parse_proof_success_reply (struct 
TALER_KYCLOGIC_ProofHandle *ph,
             "Unexpected response from KYC gateway: data must contain id");
       ph->http_status
         = MHD_HTTP_BAD_GATEWAY;
-      GNUNET_JSON_parse_free (spec);
       return;
     }
     ph->status = TALER_KYCLOGIC_STATUS_SUCCESS;
@@ -1034,7 +1032,6 @@ parse_proof_success_reply (struct 
TALER_KYCLOGIC_ProofHandle *ph,
   }
   ph->attributes = data2attributes (ph->pd,
                                     data);
-  GNUNET_JSON_parse_free (spec);
 }
 
 
diff --git a/src/kyclogic/plugin_kyclogic_persona.c 
b/src/kyclogic/plugin_kyclogic_persona.c
index e14a5039..40630783 100644
--- a/src/kyclogic/plugin_kyclogic_persona.c
+++ b/src/kyclogic/plugin_kyclogic_persona.c
@@ -1113,17 +1113,17 @@ handle_proof_finished (void *cls,
       const char *inquiry_id;
       const char *account_id;
       const char *type = NULL;
-      json_t *attributes;
-      json_t *relationships;
+      const json_t *attributes;
+      const json_t *relationships;
       struct GNUNET_JSON_Specification spec[] = {
         GNUNET_JSON_spec_string ("type",
                                  &type),
         GNUNET_JSON_spec_string ("id",
                                  &inquiry_id),
-        GNUNET_JSON_spec_json ("attributes",
-                               &attributes),
-        GNUNET_JSON_spec_json ("relationships",
-                               &relationships),
+        GNUNET_JSON_spec_object_const ("attributes",
+                                       &attributes),
+        GNUNET_JSON_spec_object_const ("relationships",
+                                       &relationships),
         GNUNET_JSON_spec_end ()
       };
 
@@ -1141,7 +1141,6 @@ handle_proof_finished (void *cls,
                                  inquiry_id,
                                  "data",
                                  data);
-        GNUNET_JSON_parse_free (spec);
         break;
       }
 
@@ -1172,8 +1171,6 @@ handle_proof_finished (void *cls,
                                    inquiry_id,
                                    "data-attributes",
                                    data);
-          GNUNET_JSON_parse_free (ispec);
-          GNUNET_JSON_parse_free (spec);
           break;
         }
         {
@@ -1192,8 +1189,6 @@ handle_proof_finished (void *cls,
                                      inquiry_id,
                                      "data-attributes-reference_id",
                                      data);
-            GNUNET_JSON_parse_free (ispec);
-            GNUNET_JSON_parse_free (spec);
             break;
           }
         }
@@ -1207,8 +1202,6 @@ handle_proof_finished (void *cls,
                                    inquiry_id,
                                    "data-id",
                                    data);
-          GNUNET_JSON_parse_free (ispec);
-          GNUNET_JSON_parse_free (spec);
           break;
         }
 
@@ -1240,8 +1233,6 @@ handle_proof_finished (void *cls,
                 GNUNET_JSON_pack_object_incref ("data",
                                                 (json_t *)
                                                 data))));
-          GNUNET_JSON_parse_free (ispec);
-          GNUNET_JSON_parse_free (spec);
           break;
         }
 
@@ -1260,9 +1251,7 @@ handle_proof_finished (void *cls,
                                    j,
                                    &proof_post_conversion_cb,
                                    ph);
-        GNUNET_JSON_parse_free (ispec);
       }
-      GNUNET_JSON_parse_free (spec);
       return; /* continued in proof_post_conversion_cb */
     }
   case MHD_HTTP_BAD_REQUEST:
@@ -1649,17 +1638,17 @@ handle_webhook_finished (void *cls,
       const char *inquiry_id;
       const char *account_id;
       const char *type = NULL;
-      json_t *attributes;
-      json_t *relationships;
+      const json_t *attributes;
+      const json_t *relationships;
       struct GNUNET_JSON_Specification spec[] = {
         GNUNET_JSON_spec_string ("type",
                                  &type),
         GNUNET_JSON_spec_string ("id",
                                  &inquiry_id),
-        GNUNET_JSON_spec_json ("attributes",
-                               &attributes),
-        GNUNET_JSON_spec_json ("relationships",
-                               &relationships),
+        GNUNET_JSON_spec_object_const ("attributes",
+                                       &attributes),
+        GNUNET_JSON_spec_object_const ("relationships",
+                                       &relationships),
         GNUNET_JSON_spec_end ()
       };
 
@@ -1709,8 +1698,6 @@ handle_webhook_finished (void *cls,
           webhook_reply_error (wh,
                                inquiry_id,
                                MHD_HTTP_BAD_GATEWAY);
-          GNUNET_JSON_parse_free (ispec);
-          GNUNET_JSON_parse_free (spec);
           break;
         }
         {
@@ -1727,8 +1714,6 @@ handle_webhook_finished (void *cls,
             webhook_reply_error (wh,
                                  inquiry_id,
                                  MHD_HTTP_BAD_GATEWAY);
-            GNUNET_JSON_parse_free (ispec);
-            GNUNET_JSON_parse_free (spec);
             break;
           }
         }
@@ -1740,8 +1725,6 @@ handle_webhook_finished (void *cls,
           webhook_reply_error (wh,
                                inquiry_id,
                                MHD_HTTP_BAD_GATEWAY);
-          GNUNET_JSON_parse_free (ispec);
-          GNUNET_JSON_parse_free (spec);
           break;
         }
 
@@ -1763,8 +1746,6 @@ handle_webhook_finished (void *cls,
                                  inquiry_id,
                                  NULL,
                                  MHD_HTTP_OK);
-          GNUNET_JSON_parse_free (ispec);
-          GNUNET_JSON_parse_free (spec);
           break;
         }
 
@@ -1784,9 +1765,7 @@ handle_webhook_finished (void *cls,
                                    j,
                                    &webhook_post_conversion_cb,
                                    wh);
-        GNUNET_JSON_parse_free (ispec);
       }
-      GNUNET_JSON_parse_free (spec);
       return; /* continued in webhook_post_conversion_cb */
     }
   case MHD_HTTP_BAD_REQUEST:
diff --git a/src/lib/exchange_api_batch_deposit.c 
b/src/lib/exchange_api_batch_deposit.c
index c583d5ad..544407a3 100644
--- a/src/lib/exchange_api_batch_deposit.c
+++ b/src/lib/exchange_api_batch_deposit.c
@@ -237,12 +237,12 @@ handle_deposit_finished (void *cls,
   case MHD_HTTP_OK:
     {
       const struct TALER_EXCHANGE_Keys *key_state;
-      json_t *sigs;
+      const json_t *sigs;
       json_t *sig;
       unsigned int idx;
       struct GNUNET_JSON_Specification spec[] = {
-        GNUNET_JSON_spec_json ("exchange_sigs",
-                               &sigs),
+        GNUNET_JSON_spec_array_const ("exchange_sigs",
+                                      &sigs),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
                                      &dh->exchange_pub),
         GNUNET_JSON_spec_mark_optional (
@@ -269,7 +269,6 @@ handle_deposit_finished (void *cls,
         GNUNET_break_op (0);
         dr.hr.http_status = 0;
         dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
-        GNUNET_JSON_parse_free (spec);
         break;
       }
       dh->exchange_sigs = GNUNET_new_array (dh->num_cdds,
@@ -282,7 +281,6 @@ handle_deposit_finished (void *cls,
         GNUNET_break_op (0);
         dr.hr.http_status = 0;
         dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
-        GNUNET_JSON_parse_free (spec);
         break;
       }
       json_array_foreach (sigs, idx, sig)
@@ -303,7 +301,6 @@ handle_deposit_finished (void *cls,
           GNUNET_break_op (0);
           dr.hr.http_status = 0;
           dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
-          GNUNET_JSON_parse_free (spec);
           break;
         }
         dki = TALER_EXCHANGE_get_denomination_key_by_hash (key_state,
@@ -332,14 +329,12 @@ handle_deposit_finished (void *cls,
           GNUNET_break_op (0);
           dr.hr.http_status = 0;
           dr.hr.ec = TALER_EC_EXCHANGE_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE;
-          GNUNET_JSON_parse_free (spec);
           break;
         }
       }
       TEAH_get_auditors_for_dc (dh->exchange,
                                 &auditor_cb,
                                 dh);
-      GNUNET_JSON_parse_free (spec);
     }
     dr.details.ok.exchange_sigs = dh->exchange_sigs;
     dr.details.ok.exchange_pub = &dh->exchange_pub;
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
index 588b1283..8bbc6c47 100644
--- a/src/lib/exchange_api_common.c
+++ b/src/lib/exchange_api_common.c
@@ -1465,7 +1465,7 @@ enum GNUNET_GenericReturnValue
 TALER_EXCHANGE_verify_coin_history (
   const struct TALER_EXCHANGE_DenomPublicKey *dk,
   const struct TALER_CoinSpendPublicKeyP *coin_pub,
-  json_t *history,
+  const json_t *history,
   struct TALER_Amount *total)
 {
   const char *currency = dk->value.currency;
@@ -1865,7 +1865,7 @@ TALER_EXCHANGE_check_coin_amount_conflict_ (
   struct TALER_CoinSpendPublicKeyP *coin_pub,
   struct TALER_Amount *remaining)
 {
-  json_t *history;
+  const json_t *history;
   struct TALER_Amount total;
   struct TALER_DenominationHashP h_denom_pub;
   const struct TALER_EXCHANGE_DenomPublicKey *dki;
@@ -1874,8 +1874,8 @@ TALER_EXCHANGE_check_coin_amount_conflict_ (
                                  coin_pub),
     GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
                                  &h_denom_pub),
-    GNUNET_JSON_spec_json ("history",
-                           &history),
+    GNUNET_JSON_spec_array_const ("history",
+                                  &history),
     GNUNET_JSON_spec_end ()
   };
 
@@ -1902,10 +1902,8 @@ TALER_EXCHANGE_check_coin_amount_conflict_ (
                                           &total))
   {
     GNUNET_break_op (0);
-    json_decref (history);
     return GNUNET_SYSERR;
   }
-  json_decref (history);
   if (0 >
       TALER_amount_subtract (remaining,
                              &dki->value,
@@ -2298,8 +2296,8 @@ TALER_EXCHANGE_parse_accounts (const struct 
TALER_MasterPublicKeyP *master_pub,
        i++)
   {
     struct TALER_EXCHANGE_WireAccount *wa = &was[i];
-    json_t *credit_restrictions;
-    json_t *debit_restrictions;
+    const json_t *credit_restrictions;
+    const json_t *debit_restrictions;
     struct GNUNET_JSON_Specification spec_account[] = {
       GNUNET_JSON_spec_string ("payto_uri",
                                &wa->payto_uri),
@@ -2307,10 +2305,10 @@ TALER_EXCHANGE_parse_accounts (const struct 
TALER_MasterPublicKeyP *master_pub,
         GNUNET_JSON_spec_string ("conversion_url",
                                  &wa->conversion_url),
         NULL),
-      GNUNET_JSON_spec_json ("credit_restrictions",
-                             &credit_restrictions),
-      GNUNET_JSON_spec_json ("debit_restrictions",
-                             &debit_restrictions),
+      GNUNET_JSON_spec_array_const ("credit_restrictions",
+                                    &credit_restrictions),
+      GNUNET_JSON_spec_array_const ("debit_restrictions",
+                                    &debit_restrictions),
       GNUNET_JSON_spec_fixed_auto ("master_sig",
                                    &wa->master_sig),
       GNUNET_JSON_spec_end ()
@@ -2366,7 +2364,6 @@ TALER_EXCHANGE_parse_accounts (const struct 
TALER_MasterPublicKeyP *master_pub,
       GNUNET_break_op (0);
       return GNUNET_SYSERR;
     }
-    GNUNET_JSON_parse_free (spec_account);
   }       /* end 'for all accounts */
   return GNUNET_OK;
 }
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index 601b163d..d78b6185 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -400,7 +400,7 @@ parse_json_auditor (struct 
TALER_EXCHANGE_AuditorInformation *auditor,
                     json_t *auditor_obj,
                     const struct TALER_EXCHANGE_Keys *key_data)
 {
-  json_t *keys;
+  const json_t *keys;
   json_t *key;
   unsigned int len;
   unsigned int off;
@@ -411,8 +411,8 @@ parse_json_auditor (struct 
TALER_EXCHANGE_AuditorInformation *auditor,
                                  &auditor->auditor_pub),
     GNUNET_JSON_spec_string ("auditor_url",
                              &auditor_url),
-    GNUNET_JSON_spec_json ("denomination_keys",
-                           &keys),
+    GNUNET_JSON_spec_array_const ("denomination_keys",
+                                  &keys),
     GNUNET_JSON_spec_end ()
   };
 
@@ -492,7 +492,6 @@ parse_json_auditor (struct 
TALER_EXCHANGE_AuditorInformation *auditor,
             &auditor_sig))
       {
         GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
         return GNUNET_SYSERR;
       }
     }
@@ -501,7 +500,6 @@ parse_json_auditor (struct 
TALER_EXCHANGE_AuditorInformation *auditor,
     off++;
   }
   auditor->num_denom_keys = off;
-  GNUNET_JSON_parse_free (spec);
   return GNUNET_OK;
 }
 
@@ -734,7 +732,7 @@ decode_keys_json (const json_t *resp_obj,
   const char *currency;
   const char *asset_type;
   bool tipping_allowed = true;
-  json_t *wblwk = NULL;
+  const json_t *wblwk = NULL;
   struct GNUNET_JSON_Specification mspec[] = {
     GNUNET_JSON_spec_fixed_auto ("denominations_sig",
                                  &denominations_sig),
@@ -755,8 +753,8 @@ decode_keys_json (const json_t *resp_obj,
                              &tipping_allowed),
       NULL),
     GNUNET_JSON_spec_mark_optional (
-      GNUNET_JSON_spec_json ("wallet_balance_limit_without_kyc",
-                             &wblwk),
+      GNUNET_JSON_spec_array_const ("wallet_balance_limit_without_kyc",
+                                    &wblwk),
       NULL),
     GNUNET_JSON_spec_end ()
   };
@@ -908,14 +906,14 @@ decode_keys_json (const json_t *resp_obj,
   /* TODO: maybe lift all this into a FP in TALER_Extension ? */
   {
     struct TALER_MasterSignatureP extensions_sig = {0};
-    json_t *manifests = NULL;
+    const json_t *manifests = NULL;
     bool no_extensions = false;
     bool no_signature = false;
 
     struct GNUNET_JSON_Specification ext_spec[] = {
       GNUNET_JSON_spec_mark_optional (
-        GNUNET_JSON_spec_json ("extensions",
-                               &manifests),
+        GNUNET_JSON_spec_object_const ("extensions",
+                                       &manifests),
         &no_extensions),
       GNUNET_JSON_spec_mark_optional (
         GNUNET_JSON_spec_fixed_auto (
@@ -1707,15 +1705,15 @@ static void
 deserialize_data (struct TALER_EXCHANGE_Handle *exchange,
                   const json_t *data)
 {
-  json_t *keys;
+  const json_t *keys;
   const char *url;
   uint32_t version;
   struct GNUNET_TIME_Timestamp expire;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_uint32 ("version",
                              &version),
-    GNUNET_JSON_spec_json ("keys",
-                           &keys),
+    GNUNET_JSON_spec_array_const ("keys",
+                                  &keys),
     GNUNET_JSON_spec_string ("exchange_url",
                              &url),
     GNUNET_JSON_spec_timestamp ("expire",
@@ -1742,14 +1740,12 @@ deserialize_data (struct TALER_EXCHANGE_Handle 
*exchange,
   }
   if (0 != version)
   {
-    GNUNET_JSON_parse_free (spec);
     return; /* unsupported version */
   }
   if (0 != strcmp (url,
                    exchange->url))
   {
     GNUNET_break (0);
-    GNUNET_JSON_parse_free (spec);
     return;
   }
   memset (&key_data,
@@ -1762,7 +1758,6 @@ deserialize_data (struct TALER_EXCHANGE_Handle *exchange,
                         &kresp.details.ok.compat))
   {
     GNUNET_break (0);
-    GNUNET_JSON_parse_free (spec);
     return;
   }
   /* decode successful, initialize with the result */
@@ -1777,7 +1772,6 @@ deserialize_data (struct TALER_EXCHANGE_Handle *exchange,
   /* notify application about the key information */
   exchange->cert_cb (exchange->cert_cb_cls,
                      &kresp);
-  GNUNET_JSON_parse_free (spec);
 }
 
 
diff --git a/src/lib/exchange_api_kyc_check.c b/src/lib/exchange_api_kyc_check.c
index d1580e76..472a7d2d 100644
--- a/src/lib/exchange_api_kyc_check.c
+++ b/src/lib/exchange_api_kyc_check.c
@@ -96,7 +96,7 @@ handle_kyc_check_finished (void *cls,
     break;
   case MHD_HTTP_OK:
     {
-      json_t *kyc_details;
+      const json_t *kyc_details;
       uint32_t status;
       struct GNUNET_JSON_Specification spec[] = {
         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
@@ -105,8 +105,8 @@ handle_kyc_check_finished (void *cls,
                                      &ks.details.ok.exchange_pub),
         GNUNET_JSON_spec_timestamp ("now",
                                     &ks.details.ok.timestamp),
-        GNUNET_JSON_spec_json ("kyc_details",
-                               &kyc_details),
+        GNUNET_JSON_spec_object_const ("kyc_details",
+                                       &kyc_details),
         GNUNET_JSON_spec_uint32 ("aml_status",
                                  &status),
         GNUNET_JSON_spec_end ()
diff --git a/src/lib/exchange_api_link.c b/src/lib/exchange_api_link.c
index 3b998f23..c2b7ac0b 100644
--- a/src/lib/exchange_api_link.c
+++ b/src/lib/exchange_api_link.c
@@ -270,9 +270,10 @@ parse_link_ok (struct TALER_EXCHANGE_LinkHandle *lh,
      whilst 'i' and 'session' track the 2d array. *///
   for (session = 0; session<json_array_size (json); session++)
   {
-    json_t *jsona;
+    const json_t *jsona;
     struct GNUNET_JSON_Specification spec[] = {
-      GNUNET_JSON_spec_json ("new_coins", &jsona),
+      GNUNET_JSON_spec_array_const ("new_coins",
+                                    &jsona),
       GNUNET_JSON_spec_end ()
     };
 
@@ -285,16 +286,8 @@ parse_link_ok (struct TALER_EXCHANGE_LinkHandle *lh,
       GNUNET_break_op (0);
       return GNUNET_SYSERR;
     }
-    if (! json_is_array (jsona))
-    {
-      GNUNET_break_op (0);
-      GNUNET_JSON_parse_free (spec);
-      return GNUNET_SYSERR;
-    }
-
     /* count all coins over all sessions */
     num_coins += json_array_size (jsona);
-    GNUNET_JSON_parse_free (spec);
   }
   /* Now that we know how big the 1d array is, allocate
      and fill it. */
@@ -307,11 +300,11 @@ parse_link_ok (struct TALER_EXCHANGE_LinkHandle *lh,
     off_coin = 0;
     for (session = 0; session<json_array_size (json); session++)
     {
-      json_t *jsona;
+      const json_t *jsona;
       struct TALER_TransferPublicKeyP trans_pub;
       struct GNUNET_JSON_Specification spec[] = {
-        GNUNET_JSON_spec_json ("new_coins",
-                               &jsona),
+        GNUNET_JSON_spec_array_const ("new_coins",
+                                      &jsona),
         GNUNET_JSON_spec_fixed_auto ("transfer_pub",
                                      &trans_pub),
         GNUNET_JSON_spec_end ()
@@ -326,12 +319,6 @@ parse_link_ok (struct TALER_EXCHANGE_LinkHandle *lh,
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      if (! json_is_array (jsona))
-      {
-        GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
-        return GNUNET_SYSERR;
-      }
 
       /* decode all coins */
       for (i = 0; i<json_array_size (jsona); i++)
@@ -357,10 +344,8 @@ parse_link_ok (struct TALER_EXCHANGE_LinkHandle *lh,
       {
         GNUNET_break_op (0);
         ret = GNUNET_SYSERR;
-        GNUNET_JSON_parse_free (spec);
         break;
       }
-      GNUNET_JSON_parse_free (spec);
     } /* end of for (session) */
 
     if (off_coin == num_coins)
diff --git a/src/lib/exchange_api_lookup_aml_decision.c 
b/src/lib/exchange_api_lookup_aml_decision.c
index 9e20c83b..01e98213 100644
--- a/src/lib/exchange_api_lookup_aml_decision.c
+++ b/src/lib/exchange_api_lookup_aml_decision.c
@@ -127,13 +127,12 @@ parse_kyc_attributes (const json_t *kyc_attributes,
   json_array_foreach (kyc_attributes, idx, obj)
   {
     struct TALER_EXCHANGE_KycHistoryDetail *kyc = &kyc_attributes_ar[idx];
-    json_t *attributes = NULL;
     struct GNUNET_JSON_Specification spec[] = {
       GNUNET_JSON_spec_timestamp ("collection_time",
                                   &kyc->collection_time),
       GNUNET_JSON_spec_mark_optional (
-        GNUNET_JSON_spec_json ("attributes",
-                               &attributes),
+        GNUNET_JSON_spec_object_const ("attributes",
+                                       &kyc->attributes),
         NULL),
       GNUNET_JSON_spec_string ("provider_section",
                                &kyc->provider_section),
@@ -149,8 +148,6 @@ parse_kyc_attributes (const json_t *kyc_attributes,
       GNUNET_break_op (0);
       return GNUNET_SYSERR;
     }
-    kyc->attributes = attributes;
-    json_decref (attributes); /* this is OK, RC preserved via 'kyc_attributes' 
as long as needed! */
   }
   return GNUNET_OK;
 }
@@ -171,13 +168,13 @@ parse_decision_ok (struct 
TALER_EXCHANGE_LookupAmlDecision *lh,
     .hr.reply = json,
     .hr.http_status = MHD_HTTP_OK
   };
-  json_t *aml_history;
-  json_t *kyc_attributes;
+  const json_t *aml_history;
+  const json_t *kyc_attributes;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("aml_history",
-                           &aml_history),
-    GNUNET_JSON_spec_json ("kyc_attributes",
-                           &kyc_attributes),
+    GNUNET_JSON_spec_array_const ("aml_history",
+                                  &aml_history),
+    GNUNET_JSON_spec_array_const ("kyc_attributes",
+                                  &kyc_attributes),
     GNUNET_JSON_spec_end ()
   };
 
@@ -199,6 +196,12 @@ parse_decision_ok (struct TALER_EXCHANGE_LookupAmlDecision 
*lh,
       GNUNET_NZL (lr.details.ok.kyc_attributes_length)];
     enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR;
 
+    memset (aml_history_ar,
+            0,
+            sizeof (aml_history_ar));
+    memset (kyc_attributes_ar,
+            0,
+            sizeof (kyc_attributes_ar));
     lr.details.ok.aml_history = aml_history_ar;
     lr.details.ok.kyc_attributes = kyc_attributes_ar;
     ret = parse_aml_history (aml_history,
diff --git a/src/lib/exchange_api_lookup_aml_decisions.c 
b/src/lib/exchange_api_lookup_aml_decisions.c
index 403acb54..22222b1e 100644
--- a/src/lib/exchange_api_lookup_aml_decisions.c
+++ b/src/lib/exchange_api_lookup_aml_decisions.c
@@ -123,10 +123,10 @@ parse_decisions_ok (struct 
TALER_EXCHANGE_LookupAmlDecisions *lh,
     .hr.reply = json,
     .hr.http_status = MHD_HTTP_OK
   };
-  json_t *records;
+  const json_t *records;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("records",
-                           &records),
+    GNUNET_JSON_spec_array_const ("records",
+                                  &records),
     GNUNET_JSON_spec_end ()
   };
 
diff --git a/src/lib/exchange_api_management_get_keys.c 
b/src/lib/exchange_api_management_get_keys.c
index c649f397..df14f2e7 100644
--- a/src/lib/exchange_api_management_get_keys.c
+++ b/src/lib/exchange_api_management_get_keys.c
@@ -85,14 +85,14 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle 
*gh,
   };
   struct TALER_EXCHANGE_FutureKeys *fk
     = &gkr.details.ok.keys;
-  json_t *sk;
-  json_t *dk;
+  const json_t *sk;
+  const json_t *dk;
   bool ok;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("future_denoms",
-                           &dk),
-    GNUNET_JSON_spec_json ("future_signkeys",
-                           &sk),
+    GNUNET_JSON_spec_array_const ("future_denoms",
+                                  &dk),
+    GNUNET_JSON_spec_array_const ("future_signkeys",
+                                  &sk),
     GNUNET_JSON_spec_fixed_auto ("master_pub",
                                  &fk->master_pub),
     GNUNET_JSON_spec_fixed_auto ("denom_secmod_public_key",
@@ -127,7 +127,7 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle 
*gh,
                                 i);
     struct TALER_EXCHANGE_FutureSigningPublicKey *sign_key
       = &fk->sign_keys[i];
-    struct GNUNET_JSON_Specification spec[] = {
+    struct GNUNET_JSON_Specification ispec[] = {
       GNUNET_JSON_spec_fixed_auto ("key",
                                    &sign_key->key),
       GNUNET_JSON_spec_fixed_auto ("signkey_secmod_sig",
@@ -143,7 +143,7 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle 
*gh,
 
     if (GNUNET_OK !=
         GNUNET_JSON_parse (j,
-                           spec,
+                           ispec,
                            NULL, NULL))
     {
       GNUNET_break_op (0);
@@ -276,7 +276,6 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle 
*gh,
         break;
       }
     }
-    GNUNET_JSON_parse_free (spec);
     if (! ok)
       break;
   }
@@ -289,7 +288,6 @@ handle_ok (struct TALER_EXCHANGE_ManagementGetKeysHandle 
*gh,
     TALER_denom_pub_free (&fk->denom_keys[i].key);
   GNUNET_free (fk->sign_keys);
   GNUNET_free (fk->denom_keys);
-  GNUNET_JSON_parse_free (spec);
   return (ok) ? GNUNET_OK : GNUNET_SYSERR;
 }
 
diff --git a/src/lib/exchange_api_refreshes_reveal.c 
b/src/lib/exchange_api_refreshes_reveal.c
index 3bdef202..50de7681 100644
--- a/src/lib/exchange_api_refreshes_reveal.c
+++ b/src/lib/exchange_api_refreshes_reveal.c
@@ -107,10 +107,10 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshesRevealHandle *rrh,
                    const json_t *json,
                    struct TALER_EXCHANGE_RevealedCoinInfo *rcis)
 {
-  json_t *jsona;
+  const json_t *jsona;
   struct GNUNET_JSON_Specification outer_spec[] = {
-    GNUNET_JSON_spec_json ("ev_sigs",
-                           &jsona),
+    GNUNET_JSON_spec_array_const ("ev_sigs",
+                                  &jsona),
     GNUNET_JSON_spec_end ()
   };
 
@@ -122,18 +122,10 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshesRevealHandle *rrh,
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
   }
-  if (! json_is_array (jsona))
-  {
-    /* We expected an array of coins */
-    GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (outer_spec);
-    return GNUNET_SYSERR;
-  }
   if (rrh->md.num_fresh_coins != json_array_size (jsona))
   {
     /* Number of coins generated does not match our expectation */
     GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (outer_spec);
     return GNUNET_SYSERR;
   }
   for (unsigned int i = 0; i<rrh->md.num_fresh_coins; i++)
@@ -180,7 +172,6 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshesRevealHandle *rrh,
                            NULL, NULL))
     {
       GNUNET_break_op (0);
-      GNUNET_JSON_parse_free (outer_spec);
       return GNUNET_SYSERR;
     }
 
@@ -209,13 +200,11 @@ refresh_reveal_ok (struct 
TALER_EXCHANGE_RefreshesRevealHandle *rrh,
     {
       GNUNET_break_op (0);
       GNUNET_JSON_parse_free (spec);
-      GNUNET_JSON_parse_free (outer_spec);
       return GNUNET_SYSERR;
     }
     GNUNET_JSON_parse_free (spec);
     rci->sig = coin.sig;
   }
-  GNUNET_JSON_parse_free (outer_spec);
   return GNUNET_OK;
 }
 
diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c
index 7c9616ea..35524ca4 100644
--- a/src/lib/exchange_api_refund.c
+++ b/src/lib/exchange_api_refund.c
@@ -172,11 +172,11 @@ static enum GNUNET_GenericReturnValue
 verify_conflict_history_ok (struct TALER_EXCHANGE_RefundHandle *rh,
                             const json_t *json)
 {
-  json_t *history;
+  const json_t *history;
   struct TALER_DenominationHashP h_denom_pub;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("history",
-                           &history),
+    GNUNET_JSON_spec_array_const ("history",
+                                  &history),
     GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
                                  &h_denom_pub),
     GNUNET_JSON_spec_end ()
@@ -199,7 +199,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
   if (0 == len)
   {
     GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
     return GNUNET_SYSERR;
   }
   have_deposit = false;
@@ -225,7 +224,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                            NULL, NULL))
     {
       GNUNET_break_op (0);
-      GNUNET_JSON_parse_free (spec);
       return GNUNET_SYSERR;
     }
     if (0 == strcasecmp (type,
@@ -274,7 +272,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                              NULL, NULL))
       {
         GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
         return GNUNET_SYSERR;
       }
       if (GNUNET_OK !=
@@ -292,7 +289,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                                        &sig))
       {
         GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
         return GNUNET_SYSERR;
       }
       if ( (0 != GNUNET_memcmp (&rh->h_contract_terms,
@@ -302,7 +298,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
       {
         /* deposit information is about a different merchant/contract */
         GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
         return GNUNET_SYSERR;
       }
       if (have_deposit)
@@ -313,7 +308,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                                        &dtotal))
         {
           GNUNET_break_op (0);
-          GNUNET_JSON_parse_free (spec);
           return GNUNET_SYSERR;
         }
         GNUNET_break (0 <=
@@ -356,7 +350,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                              NULL, NULL))
       {
         GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
         return GNUNET_SYSERR;
       }
       if (0 >
@@ -365,7 +358,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                             &amount))
       {
         GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
         return GNUNET_SYSERR;
       }
       if (GNUNET_OK !=
@@ -377,7 +369,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                                         &sig))
       {
         GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
         return GNUNET_SYSERR;
       }
       if ( (0 != GNUNET_memcmp (&rh->h_contract_terms,
@@ -387,7 +378,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
       {
         /* refund is about a different merchant/contract */
         GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
         return GNUNET_SYSERR;
       }
       if (rtransaction_id == rh->rtransaction_id)
@@ -395,7 +385,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
         /* Eh, this shows either a dependency failure or idempotency,
            but must not happen in a conflict reply. Fail! */
         GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
         return GNUNET_SYSERR;
       }
 
@@ -406,7 +395,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                                        &rtotal))
         {
           GNUNET_break_op (0);
-          GNUNET_JSON_parse_free (spec);
           return GNUNET_SYSERR;
         }
         GNUNET_break (0 <=
@@ -427,7 +415,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                   "Unexpected type `%s' in response for exchange refund\n",
                   type);
       GNUNET_break_op (0);
-      GNUNET_JSON_parse_free (spec);
       return GNUNET_SYSERR;
     }
   }
@@ -440,7 +427,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                           &rh->refund_amount))
     {
       GNUNET_break (0);
-      GNUNET_JSON_parse_free (spec);
       return GNUNET_SYSERR;
     }
   }
@@ -452,7 +438,6 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
   if (! have_deposit)
   {
     GNUNET_break (0);
-    GNUNET_JSON_parse_free (spec);
     return GNUNET_SYSERR;
   }
   if (-1 != TALER_amount_cmp (&dtotal,
@@ -460,11 +445,9 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
   {
     /* rtotal <= dtotal is fine, no conflict! */
     GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
     return GNUNET_SYSERR;
   }
   /* dtotal < rtotal: that's a conflict! */
-  GNUNET_JSON_parse_free (spec);
   return GNUNET_OK;
 }
 
@@ -482,11 +465,11 @@ static enum GNUNET_GenericReturnValue
 verify_failed_dependency_ok (struct TALER_EXCHANGE_RefundHandle *rh,
                              const json_t *json)
 {
-  json_t *h;
+  const json_t *h;
   json_t *e;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("history",
-                           &h),
+    GNUNET_JSON_spec_array_const ("history",
+                                  &h),
     GNUNET_JSON_spec_end ()
   };
 
@@ -498,11 +481,9 @@ verify_failed_dependency_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
   }
-  if ( (! json_is_array (h)) ||
-       (1 != json_array_size (h) ) )
+  if (1 != json_array_size (h))
   {
     GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
     return GNUNET_SYSERR;
   }
   e = json_array_get (h, 0);
@@ -538,7 +519,6 @@ verify_failed_dependency_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                            NULL, NULL))
     {
       GNUNET_break_op (0);
-      GNUNET_JSON_parse_free (spec);
       return GNUNET_SYSERR;
     }
     if (GNUNET_OK !=
@@ -550,7 +530,6 @@ verify_failed_dependency_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                                       &sig))
     {
       GNUNET_break_op (0);
-      GNUNET_JSON_parse_free (spec);
       return GNUNET_SYSERR;
     }
     if ( (rtransaction_id != rh->rtransaction_id) ||
@@ -562,11 +541,9 @@ verify_failed_dependency_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                                  &amount)) )
     {
       GNUNET_break_op (0);
-      GNUNET_JSON_parse_free (spec);
       return GNUNET_SYSERR;
     }
   }
-  GNUNET_JSON_parse_free (spec);
   return GNUNET_OK;
 }
 
diff --git a/src/lib/exchange_api_reserves_attest.c 
b/src/lib/exchange_api_reserves_attest.c
index 0a9134e8..82d5785b 100644
--- a/src/lib/exchange_api_reserves_attest.c
+++ b/src/lib/exchange_api_reserves_attest.c
@@ -93,7 +93,7 @@ handle_reserves_attest_ok (struct 
TALER_EXCHANGE_ReservesAttestHandle *rsh,
     .hr.reply = j,
     .hr.http_status = MHD_HTTP_OK
   };
-  json_t *attributes;
+  const json_t *attributes;
   struct GNUNET_JSON_Specification spec[] = {
     GNUNET_JSON_spec_timestamp ("exchange_timestamp",
                                 &rs.details.ok.exchange_time),
@@ -103,8 +103,8 @@ handle_reserves_attest_ok (struct 
TALER_EXCHANGE_ReservesAttestHandle *rsh,
                                  &rs.details.ok.exchange_sig),
     GNUNET_JSON_spec_fixed_auto ("exchange_pub",
                                  &rs.details.ok.exchange_pub),
-    GNUNET_JSON_spec_json ("attributes",
-                           &attributes),
+    GNUNET_JSON_spec_object_const ("attributes",
+                                   &attributes),
     GNUNET_JSON_spec_end ()
   };
 
diff --git a/src/lib/exchange_api_reserves_get_attestable.c 
b/src/lib/exchange_api_reserves_get_attestable.c
index 3a5fd25d..b272d478 100644
--- a/src/lib/exchange_api_reserves_get_attestable.c
+++ b/src/lib/exchange_api_reserves_get_attestable.c
@@ -88,10 +88,10 @@ handle_reserves_get_attestable_ok (
     .hr.reply = j,
     .hr.http_status = MHD_HTTP_OK
   };
-  json_t *details;
+  const json_t *details;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("details",
-                           &details),
+    GNUNET_JSON_spec_array_const ("details",
+                                  &details),
     GNUNET_JSON_spec_end ()
   };
 
@@ -116,7 +116,6 @@ handle_reserves_get_attestable_ok (
       if (NULL == attributes[i])
       {
         GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
         return GNUNET_SYSERR;
       }
     }
@@ -126,7 +125,6 @@ handle_reserves_get_attestable_ok (
               &rs);
     rgah->cb = NULL;
   }
-  GNUNET_JSON_parse_free (spec);
   return GNUNET_OK;
 }
 
diff --git a/src/lib/exchange_api_reserves_history.c 
b/src/lib/exchange_api_reserves_history.c
index 2a0dd565..ccc11a27 100644
--- a/src/lib/exchange_api_reserves_history.c
+++ b/src/lib/exchange_api_reserves_history.c
@@ -99,7 +99,7 @@ static enum GNUNET_GenericReturnValue
 handle_reserves_history_ok (struct TALER_EXCHANGE_ReservesHistoryHandle *rsh,
                             const json_t *j)
 {
-  json_t *history;
+  const json_t *history;
   unsigned int len;
   struct TALER_EXCHANGE_ReserveHistory rs = {
     .hr.reply = j,
@@ -110,8 +110,8 @@ handle_reserves_history_ok (struct 
TALER_EXCHANGE_ReservesHistoryHandle *rsh,
   struct GNUNET_JSON_Specification spec[] = {
     TALER_JSON_spec_amount_any ("balance",
                                 &rs.details.ok.balance),
-    GNUNET_JSON_spec_json ("history",
-                           &history),
+    GNUNET_JSON_spec_array_const ("history",
+                                  &history),
     GNUNET_JSON_spec_end ()
   };
 
@@ -143,7 +143,6 @@ handle_reserves_history_ok (struct 
TALER_EXCHANGE_ReservesHistoryHandle *rsh,
       GNUNET_break_op (0);
       TALER_EXCHANGE_free_reserve_history (rhistory,
                                            len);
-      GNUNET_JSON_parse_free (spec);
       return GNUNET_SYSERR;
     }
     if (NULL != rsh->cb)
@@ -157,7 +156,6 @@ handle_reserves_history_ok (struct 
TALER_EXCHANGE_ReservesHistoryHandle *rsh,
     TALER_EXCHANGE_free_reserve_history (rhistory,
                                          len);
   }
-  GNUNET_JSON_parse_free (spec);
   return GNUNET_OK;
 }
 
diff --git a/src/lib/exchange_api_reserves_status.c 
b/src/lib/exchange_api_reserves_status.c
index 27f63d24..57fb0427 100644
--- a/src/lib/exchange_api_reserves_status.c
+++ b/src/lib/exchange_api_reserves_status.c
@@ -89,7 +89,7 @@ static enum GNUNET_GenericReturnValue
 handle_reserves_status_ok (struct TALER_EXCHANGE_ReservesStatusHandle *rsh,
                            const json_t *j)
 {
-  json_t *history;
+  const json_t *history;
   unsigned int len;
   struct TALER_EXCHANGE_ReserveStatus rs = {
     .hr.reply = j,
@@ -98,8 +98,8 @@ handle_reserves_status_ok (struct 
TALER_EXCHANGE_ReservesStatusHandle *rsh,
   struct GNUNET_JSON_Specification spec[] = {
     TALER_JSON_spec_amount_any ("balance",
                                 &rs.details.ok.balance),
-    GNUNET_JSON_spec_json ("history",
-                           &history),
+    GNUNET_JSON_spec_array_const ("history",
+                                  &history),
     GNUNET_JSON_spec_end ()
   };
 
@@ -145,7 +145,6 @@ handle_reserves_status_ok (struct 
TALER_EXCHANGE_ReservesStatusHandle *rsh,
     TALER_EXCHANGE_free_reserve_history (rhistory,
                                          len);
   }
-  GNUNET_JSON_parse_free (spec);
   return GNUNET_OK;
 }
 
diff --git a/src/lib/exchange_api_transfers_get.c 
b/src/lib/exchange_api_transfers_get.c
index f00e36ce..3a5a64fd 100644
--- a/src/lib/exchange_api_transfers_get.c
+++ b/src/lib/exchange_api_transfers_get.c
@@ -84,7 +84,7 @@ check_transfers_get_response_ok (
   struct TALER_EXCHANGE_TransfersGetHandle *wdh,
   const json_t *json)
 {
-  json_t *details_j;
+  const json_t *details_j;
   struct TALER_Amount total_expected;
   struct TALER_MerchantPublicKeyP merchant_pub;
   struct TALER_EXCHANGE_TransfersGetResponse tgr = {
@@ -104,8 +104,8 @@ check_transfers_get_response_ok (
                                  &td->h_payto),
     GNUNET_JSON_spec_timestamp ("execution_time",
                                 &td->execution_time),
-    GNUNET_JSON_spec_json ("deposits",
-                           &details_j),
+    GNUNET_JSON_spec_array_const ("deposits",
+                                  &details_j),
     GNUNET_JSON_spec_fixed_auto ("exchange_sig",
                                  &td->exchange_sig),
     GNUNET_JSON_spec_fixed_auto ("exchange_pub",
@@ -126,7 +126,6 @@ check_transfers_get_response_ok (
                              &total_expected))
   {
     GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
     return GNUNET_SYSERR;
   }
   if (GNUNET_OK !=
@@ -135,7 +134,6 @@ check_transfers_get_response_ok (
         &td->exchange_pub))
   {
     GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
     return GNUNET_SYSERR;
   }
   td->details_length = json_array_size (details_j);
@@ -181,7 +179,6 @@ check_transfers_get_response_ok (
       {
         GNUNET_break_op (0);
         GNUNET_CRYPTO_hash_context_abort (hash_context);
-        GNUNET_JSON_parse_free (spec);
         GNUNET_free (details);
         return GNUNET_SYSERR;
       }
@@ -211,7 +208,6 @@ check_transfers_get_response_ok (
             &td->exchange_sig))
       {
         GNUNET_break_op (0);
-        GNUNET_JSON_parse_free (spec);
         GNUNET_free (details);
         return GNUNET_SYSERR;
       }
@@ -223,7 +219,6 @@ check_transfers_get_response_ok (
                                &td->wire_fee))
     {
       GNUNET_break_op (0);
-      GNUNET_JSON_parse_free (spec);
       GNUNET_free (details);
       return GNUNET_SYSERR;
     }
@@ -232,7 +227,6 @@ check_transfers_get_response_ok (
                           &td->total_amount))
     {
       GNUNET_break_op (0);
-      GNUNET_JSON_parse_free (spec);
       GNUNET_free (details);
       return GNUNET_SYSERR;
     }
@@ -240,7 +234,6 @@ check_transfers_get_response_ok (
              &tgr);
     GNUNET_free (details);
   }
-  GNUNET_JSON_parse_free (spec);
   return GNUNET_OK;
 }
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]