exchange

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

commit 3860df1a7426c486f42463cf95811bbc247b5149
parent da218509aa514bc961bbfdc2b8f64752d8885bc7
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Sat, 11 Jul 2026 18:51:28 +0200

-bugfixes

Diffstat:
Msrc/exchange/taler-exchange-aggregator.c | 16+++++++++++++++-
Msrc/exchange/taler-exchange-httpd_get-aml-OFFICER_PUB-accounts.c | 36+++++++++++++++++++++++++++---------
Msrc/exchangedb/select_withdrawals_above_serial_id.c | 8++++++--
3 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/src/exchange/taler-exchange-aggregator.c b/src/exchange/taler-exchange-aggregator.c @@ -1060,14 +1060,28 @@ do_aggregate (struct AggregationUnit *au) &end_date, &au->fees, &master_sig); - if (0 >= qs) + switch (qs) { + case GNUNET_DB_STATUS_HARD_ERROR: + GNUNET_break (0); + fail_aggregation (au); + return; + case GNUNET_DB_STATUS_SOFT_ERROR: + /* serializiability issue, try again */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Serialization issue, trying again later!\n"); + rollback_aggregation (au); + return; + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not get wire fees for %s at %s. Aborting run.\n", au->wa->method, GNUNET_TIME_timestamp2s (au->execution_time)); fail_aggregation (au); return; + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + /* continued below */ + break; } } diff --git a/src/exchange/taler-exchange-httpd_get-aml-OFFICER_PUB-accounts.c b/src/exchange/taler-exchange-httpd_get-aml-OFFICER_PUB-accounts.c @@ -202,16 +202,22 @@ record_cb ( ecomments = TALER_escape_xml (comments); tt = (time_t) GNUNET_TIME_timestamp_to_s (open_time); tm = gmtime (&tt); - strftime (opentime_s, - sizeof (opentime_s), - "%Y-%m-%dT%H:%M:%S", - tm); + if (NULL != tm) + strftime (opentime_s, + sizeof (opentime_s), + "%Y-%m-%dT%H:%M:%S", + tm); + else + opentime_s[0] = '\0'; tt = (time_t) GNUNET_TIME_timestamp_to_s (close_time); tm = gmtime (&tt); - strftime (closetime_s, - sizeof (closetime_s), - "%Y-%m-%dT%H:%M:%S", - tm); + if (NULL != tm) + strftime (closetime_s, + sizeof (closetime_s), + "%Y-%m-%dT%H:%M:%S", + tm); + else + closetime_s[0] = '\0'; GNUNET_buffer_write_fstr ( &rc->details.xml, "<Row>" @@ -248,9 +254,11 @@ record_cb ( case RCF_CSV: { char *ecomments; + char *epayto; char otbuf[64]; char ctbuf[64]; size_t len = strlen (comments); + size_t plen = strlen (payto.full_payto); size_t wpos = 0; GNUNET_snprintf (otbuf, @@ -269,10 +277,19 @@ record_cb ( ecomments[wpos++] = '"'; ecomments[wpos++] = comments[off]; } + /* Escape 'payto' to double '"' as per RFC 4180, 2.7. */ + epayto = GNUNET_malloc (2 * plen + 1); + wpos = 0; + for (size_t off = 0; off<plen; off++) + { + if ('"' == payto.full_payto[off]) + epayto[wpos++] = '"'; + epayto[wpos++] = payto.full_payto[off]; + } GNUNET_buffer_write_fstr (&rc->details.csv, "%llu,\"%s\",\"%s\",%s,%s,%s\r\n", (unsigned long long) row_id, - payto.full_payto, + epayto, ecomments, high_risk ? "X":" ", GNUNET_TIME_absolute_is_never (open_time. @@ -284,6 +301,7 @@ record_cb ( ? "-" : ctbuf); GNUNET_free (ecomments); + GNUNET_free (epayto); break; } /* end case RCF_CSV */ } /* end switch */ diff --git a/src/exchangedb/select_withdrawals_above_serial_id.c b/src/exchangedb/select_withdrawals_above_serial_id.c @@ -135,8 +135,12 @@ withdraw_serial_helper_cb (void *cls, GNUNET_PQ_cleanup_result (rs); return; } - if ((! no_max_age) && - ((255 <= noreveal_index) || (255 <= max_age))) + /* Note: here we just check that the uint8_t + limitations are met, other constraints are checked later */ + if (( (! no_noreveal_index) && + (UINT8_MAX <= noreveal_index)) || + ( (! no_max_age) && + (UINT8_MAX <= max_age))) { GNUNET_break (0); rosc->status = GNUNET_SYSERR;