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:
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[]"