exchange

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

commit 49317c7d1787ee7c5917490dd14eae04a9249f11
parent 19cbf79be97f9b4311da38f2890dea902aa9349c
Author: Özgür Kesim <oec@codeblau.de>
Date:   Fri,  9 Jan 2026 14:09:57 +0100

[pq] correctly handle non-NULL but empty array of amounts

Fixes #10857

Diffstat:
Msrc/pq/pq_result_helper.c | 38+++++++++++++++++++++++++++++---------
Msrc/pq/test_pq.c | 24+++++++++++++++++++++---
2 files changed, 50 insertions(+), 12 deletions(-)

diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2023 Taler Systems SA + Copyright (C) 2014-2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -17,6 +17,7 @@ * @file pq/pq_result_helper.c * @brief functions to initialize parameter arrays * @author Christian Grothoff + * @author Özgür Kesim */ #include "taler/platform.h" #include <gnunet/gnunet_util_lib.h> @@ -1163,13 +1164,13 @@ extract_array_generic ( *((void **) dst) = NULL; #define FAIL_IF(cond) \ - do { \ - if ((cond)) \ - { \ - GNUNET_break (! (cond)); \ - goto FAIL; \ - } \ - } while (0) + do { \ + if ((cond)) \ + { \ + GNUNET_break (! (cond)); \ + goto FAIL; \ + } \ + } while (0) col_num = PQfnumber (result, fname); FAIL_IF (0 > col_num); @@ -1181,9 +1182,28 @@ extract_array_generic ( data_sz = PQgetlength (result, row, col_num); FAIL_IF (0 > data_sz); - FAIL_IF (sizeof(header) > (size_t) data_sz); + + /* Report if this field is empty */ + if (0 == (size_t) data_sz) + return GNUNET_NO; data = PQgetvalue (result, row, col_num); + + if (sizeof(header) > (size_t) data_sz) + { + uint32_t ndim; + + /* data_sz is shorter than header if the + array length is 0, in which case ndim is 0! */ + FAIL_IF (sizeof(uint32_t) > (size_t) data_sz); + memcpy (&ndim, + data, + sizeof (ndim)); + FAIL_IF (0 != ndim); + *info->num = 0; + return GNUNET_OK; + } + FAIL_IF (sizeof(header) > (size_t) data_sz); FAIL_IF (NULL == data); { diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c @@ -1,6 +1,6 @@ /* This file is part of TALER - (C) 2015, 2016, 2023 Taler Systems SA + (C) 2015, 2016, 2023, 2026 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -17,6 +17,7 @@ * @file pq/test_pq.c * @brief Tests for Postgres convenience API * @author Christian Grothoff <christian@grothoff.org> + * @author Özgür Kesim <oec-taler@kesim.org> */ #include "taler/platform.h" #include "taler/taler_util.h" @@ -36,7 +37,7 @@ postgres_prepare (struct GNUNET_PQ_Context *db) struct GNUNET_PQ_PreparedStatement ps[] = { GNUNET_PQ_make_prepare ("test_insert", "INSERT INTO test_pq (" - " tamount" + "tamount" ",json" ",aamount" ",aamountc" @@ -52,6 +53,8 @@ postgres_prepare (struct GNUNET_PQ_Context *db) ",json" ",aamount" ",aamountc" + ",aamountn" + ",aamountnc" ",tamountc" ",hash" ",hashes" @@ -177,11 +180,15 @@ run_queries (struct GNUNET_PQ_Context *conn) struct TALER_Amount tamountc2; struct TALER_Amount *pamount; struct TALER_Amount *pamountc; + struct TALER_Amount *pamountn; + struct TALER_Amount *pamountnc; struct GNUNET_HashCode hc2; struct GNUNET_HashCode *hcs2; struct GNUNET_CRYPTO_CSPublicRPairP *out_cs_r_pubs; size_t npamount; size_t npamountc; + size_t npamountn; + size_t npamountnc; size_t nhcs; size_t n_rpubs; json_t *json2; @@ -203,6 +210,15 @@ run_queries (struct GNUNET_PQ_Context *conn) "aamountc", &npamountc, &pamountc), + TALER_PQ_result_spec_array_amount (conn, + "aamountn", + "EUR", + &npamountn, + &pamountn), + TALER_PQ_result_spec_array_amount_with_currency (conn, + "aamountnc", + &npamountnc, + &pamountnc), TALER_PQ_result_spec_amount_with_currency ("tamountc", &tamountc2), GNUNET_PQ_result_spec_auto_from_type ("hash", @@ -305,10 +321,12 @@ main (int argc, " END " "$$;"), GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS test_pq (" - " tamount taler_amount NOT NULL" + "tamount taler_amount NOT NULL" ",json VARCHAR NOT NULL" ",aamount taler_amount[]" ",aamountc taler_amount_currency[]" + ",aamountn taler_amount[] NOT NULL DEFAULT ARRAY[]::taler_amount[]" + ",aamountnc taler_amount_currency[] NOT NULL DEFAULT ARRAY[]::taler_amount_currency[]" ",tamountc taler_amount_currency" ",hash gnunet_hashcode" ",hashes gnunet_hashcode[]"