exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit 1262e2462d4b6c51e91122bd70ea9f893a01de27
parent c93d9ab4deacb67523b9678cf3916f2ceeb7daec
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon, 29 Jun 2026 17:05:49 +0200

bugfixes

Diffstat:
Msrc/exchange/taler-exchange-httpd_post-batch-deposit.c | 7++++++-
Msrc/exchange/taler-exchange-httpd_post-kyc-wallet.c | 5+++++
Msrc/exchange/taler-exchange-httpd_post-purses-PURSE_PUB-merge.c | 5+++++
Msrc/exchange/taler-exchange-httpd_post-reserves-RESERVE_PUB-purse.c | 5+++++
Msrc/exchange/taler-exchange-httpd_post-reveal-melt.c | 1+
Msrc/exchangedb/get_refresh.c | 8++++----
Msrc/include/exchange-database/get_refresh.h | 8++++----
Msrc/lib/exchange_api_post-withdraw.c | 10++++++++--
Msrc/lib/exchange_api_post-withdraw_blinded.c | 8+++++---
Msrc/testing/testing_api_cmd_age_withdraw.c | 15+++++++++++----
10 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/src/exchange/taler-exchange-httpd_post-batch-deposit.c b/src/exchange/taler-exchange-httpd_post-batch-deposit.c @@ -597,7 +597,6 @@ bdc_phase_kyc (struct BatchDepositContext *bdc) } - /** * Parse per-coin deposit information from @a jcoin * into @a deposit. Fill in generic information from @@ -1066,6 +1065,11 @@ bdc_cleaner (struct TEH_RequestContext *rc) TALER_denom_sig_free (&bdc->cdis[i].coin.denom_sig); GNUNET_free (bdc->cdis); } + if (NULL != bdc->response) + { + MHD_destroy_response (bdc->response); + bdc->response = NULL; + } GNUNET_free (bdc->deposit_fees); GNUNET_free (bdc); } @@ -1118,6 +1122,7 @@ TEH_handler_batch_deposit (struct TEH_RequestContext *rc, bdc_phase_check_kyc_result (bdc); break; case BDC_PHASE_GENERATE_REPLY_FAILURE: + GNUNET_assert (NULL != bdc->response); return MHD_queue_response (bdc->rc->connection, bdc->http_status, bdc->response); diff --git a/src/exchange/taler-exchange-httpd_post-kyc-wallet.c b/src/exchange/taler-exchange-httpd_post-kyc-wallet.c @@ -215,6 +215,11 @@ krc_cleaner (struct TEH_RequestContext *rc) TEH_legitimization_check_cancel (krc->lch); krc->lch = NULL; } + if (NULL != krc->response) + { + MHD_destroy_response (krc->response); + krc->response = NULL; + } GNUNET_free (krc->payto_uri.normalized_payto); GNUNET_free (krc); } diff --git a/src/exchange/taler-exchange-httpd_post-purses-PURSE_PUB-merge.c b/src/exchange/taler-exchange-httpd_post-purses-PURSE_PUB-merge.c @@ -512,6 +512,11 @@ clean_purse_merge_rc (struct TEH_RequestContext *rc) TEH_legitimization_check_cancel (pmc->lch); pmc->lch = NULL; } + if (NULL != pmc->response) + { + MHD_destroy_response (pmc->response); + pmc->response = NULL; + } GNUNET_free (pmc->provider_url); GNUNET_free (pmc); } diff --git a/src/exchange/taler-exchange-httpd_post-reserves-RESERVE_PUB-purse.c b/src/exchange/taler-exchange-httpd_post-reserves-RESERVE_PUB-purse.c @@ -586,6 +586,11 @@ rpc_cleaner (struct TEH_RequestContext *rc) TEH_legitimization_check_cancel (rpc->lch); rpc->lch = NULL; } + if (NULL != rpc->response) + { + MHD_destroy_response (rpc->response); + rpc->response = NULL; + } GNUNET_free (rpc->econtract.econtract); GNUNET_free (rpc->payto_uri.normalized_payto); GNUNET_free (rpc); diff --git a/src/exchange/taler-exchange-httpd_post-reveal-melt.c b/src/exchange/taler-exchange-httpd_post-reveal-melt.c @@ -896,6 +896,7 @@ TEH_handler_reveal_melt ( if (NULL != actx.refresh.denom_sigs) for (unsigned int i = 0; i<actx.refresh.num_coins; i++) TALER_blinded_denom_sig_free (&actx.refresh.denom_sigs[i]); + GNUNET_free (actx.refresh.transfer_pubs); GNUNET_free (actx.refresh.denom_sigs); GNUNET_free (actx.refresh.denom_pub_hashes); GNUNET_free (actx.refresh.denom_serials); diff --git a/src/exchangedb/get_refresh.c b/src/exchangedb/get_refresh.c @@ -24,10 +24,10 @@ enum GNUNET_DB_QueryStatus -TALER_EXCHANGEDB_get_refresh (struct TALER_EXCHANGEDB_PostgresContext *pg, - const struct TALER_RefreshCommitmentP *rc, - struct TALER_EXCHANGEDB_Refresh_vDOLDPLUS *refresh - ) +TALER_EXCHANGEDB_get_refresh ( + struct TALER_EXCHANGEDB_PostgresContext *pg, + const struct TALER_RefreshCommitmentP *rc, + struct TALER_EXCHANGEDB_Refresh_vDOLDPLUS *refresh) { struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_auto_from_type (rc), diff --git a/src/include/exchange-database/get_refresh.h b/src/include/exchange-database/get_refresh.h @@ -34,9 +34,9 @@ * @return transaction status */ enum GNUNET_DB_QueryStatus -TALER_EXCHANGEDB_get_refresh (struct TALER_EXCHANGEDB_PostgresContext *pg, - const struct TALER_RefreshCommitmentP *rc, - struct TALER_EXCHANGEDB_Refresh_vDOLDPLUS *refresh - ); +TALER_EXCHANGEDB_get_refresh ( + struct TALER_EXCHANGEDB_PostgresContext *pg, + const struct TALER_RefreshCommitmentP *rc, + struct TALER_EXCHANGEDB_Refresh_vDOLDPLUS *refresh); #endif diff --git a/src/lib/exchange_api_post-withdraw.c b/src/lib/exchange_api_post-withdraw.c @@ -418,7 +418,6 @@ copy_results_with_age_proof ( { /* The original handle from the top-level call to withdraw */ struct TALER_EXCHANGE_PostWithdrawHandle *wh = cls; - uint8_t k = wbr->details.created.noreveal_index; struct TALER_EXCHANGE_WithdrawCoinPrivateDetails details[wh->num_coins]; struct TALER_EXCHANGE_PostWithdrawResponse resp = { .hr = wbr->hr, @@ -433,6 +432,9 @@ copy_results_with_age_proof ( break; case MHD_HTTP_CREATED: { + uint8_t k = wbr->details.created.noreveal_index; + + GNUNET_assert (k < TALER_CNC_KAPPA); GNUNET_assert (wh->num_coins == wbr->details.created.num_coins); resp.details.created = wbr->details.created; resp.details.created.coin_details = details; @@ -445,8 +447,8 @@ copy_results_with_age_proof ( details[n] = wh->coin_data[n].candidates[k].details; details[n].planchet = wh->coin_data[n].planchet_details[k]; } - break; } + break; case MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS: resp.details.unavailable_for_legal_reasons = wbr->details.unavailable_for_legal_reasons; @@ -600,6 +602,7 @@ blinding_prepare_done ( success = false; /* Complete the initialization of the coin with CS denomination */ + GNUNET_assert (cs_idx < bpr->details.ok.num_blinding_values); TALER_denom_ewv_copy ( &can->details.blinding_values, &bpr->details.ok.blinding_values[cs_idx]); @@ -1048,7 +1051,10 @@ TALER_EXCHANGE_post_withdraw_start ( pwh->num_bp_nonce_keys, pwh->bp_nonce_keys); if (NULL == pwh->blinding_prepare_handle) + { + GNUNET_break (0); return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE; + } { enum TALER_ErrorCode ec = TALER_EXCHANGE_post_blinding_prepare_start ( diff --git a/src/lib/exchange_api_post-withdraw_blinded.c b/src/lib/exchange_api_post-withdraw_blinded.c @@ -292,7 +292,11 @@ withdraw_blinded_created ( GNUNET_break_op (0); return GNUNET_SYSERR; } - + if (response.details.created.noreveal_index >= TALER_CNC_KAPPA) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } if (GNUNET_OK != TALER_exchange_online_withdraw_age_confirmation_verify ( &wbh->planchets_h, @@ -302,9 +306,7 @@ withdraw_blinded_created ( { GNUNET_break_op (0); return GNUNET_SYSERR; - } - wbh->callback (wbh->callback_cls, &response); /* make sure the callback isn't called again */ diff --git a/src/testing/testing_api_cmd_age_withdraw.c b/src/testing/testing_api_cmd_age_withdraw.c @@ -631,6 +631,7 @@ age_reveal_withdraw_cb ( case MHD_HTTP_OK: { const struct AgeWithdrawState *aws = awrs->aws; + GNUNET_assert (awrs->num_coins == response->details.ok.num_sigs); awrs->denom_sigs = GNUNET_new_array (awrs->num_coins, struct TALER_DenominationSignature); @@ -644,12 +645,10 @@ age_reveal_withdraw_cb ( &aws->coin_outputs[n].details.h_coin_pub, &aws->coin_outputs[n].details.blinding_values, &aws->denoms_pub[n].key)); - TALER_denom_sig_free (&awrs->denom_sigs[n]); } GNUNET_log (GNUNET_ERROR_TYPE_INFO, "age-withdraw reveal success!\n"); - GNUNET_free (awrs->denom_sigs); } break; case MHD_HTTP_NOT_FOUND: @@ -754,8 +753,14 @@ age_reveal_withdraw_cleanup ( TALER_EXCHANGE_post_reveal_withdraw_cancel (awrs->handle); awrs->handle = NULL; } - GNUNET_free (awrs->denom_sigs); - awrs->denom_sigs = NULL; + if (NULL != awrs->denom_sigs) + { + for (size_t n = 0; n < awrs->num_coins; n++) + { + TALER_denom_sig_free (&awrs->denom_sigs[n]); + } + GNUNET_free (awrs->denom_sigs); + } GNUNET_free (awrs); } @@ -785,6 +790,8 @@ age_reveal_withdraw_traits ( TALER_TESTING_trait_end () }; + if (NULL == awrs->denom_sigs) + return GNUNET_NO; if (idx >= awrs->num_coins) return GNUNET_NO;