merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

commit 4d98c64f27ac18a7fca646a687446e246faa1bd4
parent ad270aa8ac852bd0198eb84e7f935a877d294904
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu, 26 Feb 2026 15:42:07 +0100

improve CSV logic

Diffstat:
Msrc/backend/taler-merchant-httpd_private-get-orders.c | 42+++++++++++++++++++++++++++++-------------
1 file changed, 29 insertions(+), 13 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_private-get-orders.c b/src/backend/taler-merchant-httpd_private-get-orders.c @@ -751,19 +751,35 @@ add_order (void *cls, paid)))); break; case POF_CSV: - GNUNET_buffer_write_fstr ( - &po->csv, - "%s,%llu,%llu,%s,%s,%s,\"%s\",%s,%s\r\n", - contract->order_id, - (unsigned long long) order_serial, - (unsigned long long) GNUNET_TIME_timestamp_to_s (creation_time), - amount_buf, - paid ? refund_buf : "", - paid ? pending_buf : "", - contract->summary, - refundable ? "yes" : "no", - paid ? "yes" : "no"); - break; + { + size_t len = strlen (contract->summary); + size_t wpos = 0; + char *esummary; + + /* Escape 'summary' to double '"' as per RFC 4180, 2.7. */ + esummary = GNUNET_malloc (2 * len + 1); + for (size_t off = 0; off<len; off++) + { + if ('"' == contract->summary[off]) + esummary[wpos++] = '"'; + esummary[wpos++] = contract->summary[off]; + } + + GNUNET_buffer_write_fstr ( + &po->csv, + "%s,%llu,%llu,%s,%s,%s,\"%s\",%s,%s\r\n", + contract->order_id, + (unsigned long long) order_serial, + (unsigned long long) GNUNET_TIME_timestamp_to_s (creation_time), + amount_buf, + paid ? refund_buf : "", + paid ? pending_buf : "", + esummary, + refundable ? "yes" : "no", + paid ? "yes" : "no"); + GNUNET_free (esummary); + break; + } case POF_XML: { char *esummary = TALER_escape_xml (contract->summary);