From 713db415a9bf47ffb665ee16892121829e067168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96zg=C3=BCr=20Kesim?= Date: Tue, 10 Oct 2023 13:34:47 +0200 Subject: [pq] cleanup of amount tuple type handling - add counter for tuple elements to struct - use GNUNET_memcpy instead of casting also, fix format string in test for age_restriction --- src/pq/pq_common.c | 1 + src/pq/pq_common.h | 21 +++------ src/pq/pq_query_helper.c | 30 ++++++------- src/pq/pq_result_helper.c | 97 +++++++++++++++++++++++------------------ src/pq/test_pq.c | 25 ++++++++++- src/util/test_age_restriction.c | 27 ++++++------ 6 files changed, 111 insertions(+), 90 deletions(-) diff --git a/src/pq/pq_common.c b/src/pq/pq_common.c index 59ab85f1b..8b6f8f22c 100644 --- a/src/pq/pq_common.c +++ b/src/pq/pq_common.c @@ -28,6 +28,7 @@ TALER_PQ_make_taler_pq_amount_ ( uint32_t oid_f) { struct TALER_PQ_AmountP rval = { + .cnt = htonl (2), .oid_v = htonl (oid_v), .oid_f = htonl (oid_f), .sz_v = htonl (sizeof((amount)->value)), diff --git a/src/pq/pq_common.h b/src/pq/pq_common.h index dff5e4c89..6172c0bfb 100644 --- a/src/pq/pq_common.h +++ b/src/pq/pq_common.h @@ -58,6 +58,7 @@ enum TALER_PQ_ArrayType */ struct TALER_PQ_AmountP { + uint32_t cnt; /* # elements in the tuple (== 2) */ uint32_t oid_v; /* oid of .v */ uint32_t sz_v; /* size of .v */ uint64_t v; /* value */ @@ -74,28 +75,16 @@ struct TALER_PQ_AmountP */ struct TALER_PQ_AmountCurrencyP { - uint32_t cnt; /* number of OIDs in tuple */ + uint32_t cnt; /* # elements in the tuple (== 3) */ uint32_t oid_v; /* oid of .v */ uint32_t sz_v; /* size of .v */ uint64_t v; /* value */ uint32_t oid_f; /* oid of .f */ uint32_t sz_f; /* size of .f */ uint32_t f; /* fraction */ - - /** - * oid of .c - */ - uint32_t oid_c; - - /** - * size of .c - */ - uint32_t sz_c; - - /** - * currency - */ - uint8_t c[TALER_CURRENCY_LEN]; + uint32_t oid_c; /* oid of .c */ + uint32_t sz_c; /* size of .c */ + uint8_t c[TALER_CURRENCY_LEN]; /* currency */ } __attribute__((packed)); diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c index 46719e6c2..dd6cf6733 100644 --- a/src/pq/pq_query_helper.c +++ b/src/pq/pq_query_helper.c @@ -174,13 +174,12 @@ qconv_amount_tuple (void *cls, oid_v, oid_f); - sz = sizeof(uint32_t); /* number of elements in tuple */ - sz += sizeof(d); + sz = sizeof(d); out = GNUNET_malloc (sz); scratch[0] = out; - *(uint32_t *) out = htonl (2); - out += sizeof(uint32_t); - *(struct TALER_PQ_AmountP*) out = d; + GNUNET_memcpy (out, + &d, + sizeof(d)); } } @@ -841,14 +840,14 @@ qconv_array ( same_sized = (0 != meta->same_size); #define RETURN_UNLESS(cond) \ - do { \ - if (! (cond)) \ - { \ - GNUNET_break ((cond)); \ - noerror = false; \ - goto DONE; \ - } \ - } while(0) + do { \ + if (! (cond)) \ + { \ + GNUNET_break ((cond)); \ + noerror = false; \ + goto DONE; \ + } \ + } while (0) /* Calculate sizes and check bounds */ { @@ -970,9 +969,6 @@ qconv_array ( oid_v, oid_f); - *(uint32_t *) out = htonl (2); /* number of elements in tuple */ - out += sizeof(uint32_t); - sz -= sizeof(uint32_t); GNUNET_memcpy (out, &am, sizeof(am)); @@ -1177,7 +1173,7 @@ TALER_PQ_query_param_array_amount ( true, amounts, NULL, - sizeof(uint32_t) + sizeof(struct TALER_PQ_AmountP), + sizeof(struct TALER_PQ_AmountP), TALER_PQ_array_of_amount, oid, db); diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c index 4b346e8a4..95850bcc0 100644 --- a/src/pq/pq_result_helper.c +++ b/src/pq/pq_result_helper.c @@ -81,7 +81,7 @@ extract_amount_currency_tuple (void *cls, { struct TALER_PQ_AmountCurrencyP ap; const char *in; - int size; + size_t size; size = PQgetlength (result, row, @@ -90,11 +90,11 @@ extract_amount_currency_tuple (void *cls, (size <= sizeof (ap) - TALER_CURRENCY_LEN) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Incorrect size of binary field `%s' (got %d, expected (%d-%d))\n", + "Incorrect size of binary field `%s' (got %zu, expected (%zu-%zu))\n", fname, size, - (int) (sizeof (ap) - TALER_CURRENCY_LEN), - (int) sizeof (ap)); + sizeof (ap) - TALER_CURRENCY_LEN, + sizeof (ap)); return GNUNET_SYSERR; } @@ -222,44 +222,36 @@ extract_amount_tuple (void *cls, /* Parse the tuple */ { - const char *in; - uint32_t num; struct TALER_PQ_AmountP ap; - int size; - const static int expected_size = sizeof(uint32_t) /* length */ - + sizeof(ap); + const char *in; + size_t size; size = PQgetlength (result, row, col); - - if (expected_size != size) + if (sizeof(ap) != size) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Incorrect size of binary field `%s' (got %d, expected %d)\n", + "Incorrect size of binary field `%s' (got %zu, expected %zu)\n", fname, size, - expected_size); + sizeof(ap)); return GNUNET_SYSERR; } in = PQgetvalue (result, row, col); - - num = ntohl (*(uint32_t *) in); - if (2 != num) + memcpy (&ap, + in, + size); + if (2 != ntohl (ap.cnt)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Incorrect number of elements in tuple-field `%s'\n", fname); return GNUNET_SYSERR; } - in += sizeof(uint32_t); - memcpy (&ap, - in, - sizeof (ap)); - /* TODO[oec]: OID-checks? */ r_amount->value = GNUNET_ntohll (ap.v); @@ -1084,13 +1076,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); @@ -1140,20 +1132,23 @@ extract_array_generic ( { struct TALER_PQ_AmountP ap; struct TALER_Amount *amount = &amounts[i]; - size_t sz = ntohl (*(uint32_t *) in); - in += sizeof(uint32_t); + uint32_t val; + size_t sz; + + GNUNET_memcpy (&val, + in, + sizeof(val)); + sz = ntohl (val); + in += sizeof(val); /* total size for this array-entry */ - FAIL_IF ((sizeof(uint32_t) - + sizeof(struct TALER_PQ_AmountP)) - > sz); + FAIL_IF (sizeof(ap) > sz); - /* number of elements in composite type*/ - sz = ntohl (*(uint32_t *) in); - in += sizeof(uint32_t); - FAIL_IF (2 != sz); + GNUNET_memcpy (&ap, + in, + sz); + FAIL_IF (2 != ntohl (ap.cnt)); - ap = *(struct TALER_PQ_AmountP *) in; amount->value = GNUNET_ntohll (ap.v); amount->fraction = ntohl (ap.f); GNUNET_memcpy (amount->currency, @@ -1171,7 +1166,13 @@ extract_array_generic ( *((void **) dst) = out; for (uint32_t i = 0; i < header.dim; i++) { - size_t sz = ntohl (*(uint32_t *) in); + uint32_t val; + size_t sz; + + GNUNET_memcpy (&val, + in, + sizeof(val)); + sz = ntohl (val); FAIL_IF (sz != sizeof(struct TALER_DenominationHashP)); in += sizeof(uint32_t); *(struct TALER_DenominationHashP *) out = @@ -1188,7 +1189,13 @@ extract_array_generic ( *((void **) dst) = out; for (uint32_t i = 0; i < header.dim; i++) { - size_t sz = ntohl (*(uint32_t *) in); + uint32_t val; + size_t sz; + + GNUNET_memcpy (&val, + in, + sizeof(val)); + sz = ntohl (val); FAIL_IF (sz != sizeof(struct TALER_BlindedCoinHashP)); in += sizeof(uint32_t); *(struct TALER_BlindedCoinHashP *) out = @@ -1217,10 +1224,16 @@ extract_array_generic ( { struct TALER_BlindedDenominationSignature *denom_sig = &denom_sigs[i]; uint32_t be[2]; - size_t sz = ntohl (*(uint32_t *) in); - in += sizeof(uint32_t); + uint32_t val; + size_t sz; + GNUNET_memcpy (&val, + in, + sizeof(val)); + sz = ntohl (val); FAIL_IF (sizeof(be) > sz); + + in += sizeof(val); GNUNET_memcpy (&be, in, sizeof(be)); diff --git a/src/pq/test_pq.c b/src/pq/test_pq.c index 03308ba14..237c8a9ef 100644 --- a/src/pq/test_pq.c +++ b/src/pq/test_pq.c @@ -38,13 +38,15 @@ postgres_prepare (struct GNUNET_PQ_Context *db) " tamount" ",json" ",aamount" + ",tamountc" ") VALUES " - "($1, $2, $3);"), + "($1, $2, $3, $4);"), GNUNET_PQ_make_prepare ("test_select", "SELECT" " tamount" ",json" ",aamount" + ",tamountc" " FROM test_pq;"), GNUNET_PQ_PREPARED_STATEMENT_END }; @@ -64,6 +66,7 @@ run_queries (struct GNUNET_PQ_Context *conn) { struct TALER_Amount tamount; struct TALER_Amount aamount[3]; + struct TALER_Amount tamountc; json_t *json; GNUNET_assert (GNUNET_OK == @@ -78,6 +81,9 @@ run_queries (struct GNUNET_PQ_Context *conn) GNUNET_assert (GNUNET_OK == TALER_string_to_amount ("EUR:7.7", &tamount)); + GNUNET_assert (GNUNET_OK == + TALER_string_to_amount ("FOO:8.7", + &tamountc)); json = json_object (); GNUNET_assert (NULL != json); GNUNET_assert (0 == @@ -92,6 +98,8 @@ run_queries (struct GNUNET_PQ_Context *conn) TALER_PQ_query_param_array_amount (3, aamount, conn), + TALER_PQ_query_param_amount_with_currency (conn, + &tamountc), GNUNET_PQ_query_param_end }; PGresult *result; @@ -112,6 +120,7 @@ run_queries (struct GNUNET_PQ_Context *conn) } { struct TALER_Amount tamount2; + struct TALER_Amount tamountc2; struct TALER_Amount *pamount; size_t npamount; json_t *json2; @@ -129,6 +138,8 @@ run_queries (struct GNUNET_PQ_Context *conn) "EUR", &npamount, &pamount), + TALER_PQ_result_spec_amount_with_currency ("tamountc", + &tamountc2), GNUNET_PQ_result_spec_end }; @@ -154,6 +165,9 @@ run_queries (struct GNUNET_PQ_Context *conn) TALER_amount_cmp (&aamount[i], &pamount[i])); } + GNUNET_break (0 == + TALER_amount_cmp (&tamountc, + &tamountc2)); GNUNET_PQ_cleanup_result (results_select); } return 0; @@ -173,10 +187,19 @@ main (int argc, " WHEN duplicate_object THEN null;" " END " "$$;"), + GNUNET_PQ_make_execute ("DO $$ " + " BEGIN" + " CREATE TYPE taler_amount_currency AS" + " (val INT8, frac INT4, curr VARCHAR(12));" + " EXCEPTION" + " WHEN duplicate_object THEN null;" + " END " + "$$;"), GNUNET_PQ_make_execute ("CREATE TEMPORARY TABLE IF NOT EXISTS test_pq (" " tamount taler_amount NOT NULL" ",json VARCHAR NOT NULL" ",aamount taler_amount[]" + ",tamountc taler_amount_currency" ")"), GNUNET_PQ_EXECUTE_STATEMENT_END }; diff --git a/src/util/test_age_restriction.c b/src/util/test_age_restriction.c index 02b16c3e6..61499e5e0 100644 --- a/src/util/test_age_restriction.c +++ b/src/util/test_age_restriction.c @@ -80,24 +80,24 @@ test_groups (void) .bits = 1 | 1 << 5 | 1 << 13 | 1 << 23, - .group = { 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 } + .group = { 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 } }, { .bits = 1 | 1 << 8 | 1 << 10 | 1 << 12 | 1 << 14 | 1 << 16 | 1 << 18 | 1 << 21, - .group = { 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, - 2, 2, - 3, 3, - 4, 4, - 5, 5, - 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7} + .group = { 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, + 2, 2, + 3, 3, + 4, 4, + 5, 5, + 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7} } @@ -326,9 +326,8 @@ test_attestation (void) &seed, &acp[0]); printf ( - "commit(age:%d) == %d; proof.num: %ld; age_group: %d\n", + "commit(age:%d); proof.num: %ld; age_group: %d\n", age, - ret, acp[0].proof.num, age_group); -- cgit v1.2.3