gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-exchange] branch master updated: postgres does not like 0-padding


From: gnunet
Subject: [taler-exchange] branch master updated: postgres does not like 0-padding of VARCHAR, implement proper serialization
Date: Mon, 21 Aug 2023 23:34:48 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 250e1997 postgres does not like 0-padding of VARCHAR, implement proper 
serialization
250e1997 is described below

commit 250e1997d86c160e1a6603c72b23bf1ec8eafb5d
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon Aug 21 23:34:44 2023 +0200

    postgres does not like 0-padding of VARCHAR, implement proper serialization
---
 src/pq/pq_common.c        | 32 +++++++++++++++++---------------
 src/pq/pq_common.h        |  8 ++++++--
 src/pq/pq_query_helper.c  | 29 ++++++++++++-----------------
 src/pq/pq_result_helper.c | 30 ++++++++++++++----------------
 4 files changed, 49 insertions(+), 50 deletions(-)

diff --git a/src/pq/pq_common.c b/src/pq/pq_common.c
index a548a45c..59ab85f1 100644
--- a/src/pq/pq_common.c
+++ b/src/pq/pq_common.c
@@ -40,26 +40,28 @@ TALER_PQ_make_taler_pq_amount_ (
 }
 
 
-struct TALER_PQ_AmountCurrencyP
+size_t
 TALER_PQ_make_taler_pq_amount_currency_ (
   const struct TALER_Amount *amount,
   uint32_t oid_v,
   uint32_t oid_f,
-  uint32_t oid_c)
+  uint32_t oid_c,
+  struct TALER_PQ_AmountCurrencyP *rval)
 {
-  struct TALER_PQ_AmountCurrencyP rval = {
-    .oid_v = htonl (oid_v),
-    .oid_f = htonl (oid_f),
-    .oid_c = htonl (oid_c),
-    .sz_v = htonl (sizeof((amount)->value)),
-    .sz_f = htonl (sizeof((amount)->fraction)),
-    .sz_c = htonl (TALER_CURRENCY_LEN),
-    .v = GNUNET_htonll ((amount)->value),
-    .f = htonl ((amount)->fraction),
-  };
+  size_t clen = strlen (amount->currency);
 
-  memcpy (rval.c,
+  GNUNET_assert (clen < TALER_CURRENCY_LEN);
+  rval->cnt = htonl (3);
+  rval->oid_v = htonl (oid_v);
+  rval->oid_f = htonl (oid_f);
+  rval->oid_c = htonl (oid_c);
+  rval->sz_v = htonl (sizeof(amount->value));
+  rval->sz_f = htonl (sizeof(amount->fraction));
+  rval->sz_c = htonl (clen);
+  rval->v = GNUNET_htonll (amount->value);
+  rval->f = htonl (amount->fraction);
+  memcpy (rval->c,
           amount->currency,
-          TALER_CURRENCY_LEN);
-  return rval;
+          clen);
+  return sizeof (*rval) - TALER_CURRENCY_LEN + clen;
 }
diff --git a/src/pq/pq_common.h b/src/pq/pq_common.h
index 4dc2d335..dff5e4c8 100644
--- a/src/pq/pq_common.h
+++ b/src/pq/pq_common.h
@@ -74,6 +74,7 @@ struct TALER_PQ_AmountP
  */
 struct TALER_PQ_AmountCurrencyP
 {
+  uint32_t cnt; /* number of OIDs in tuple  */
   uint32_t oid_v; /* oid of .v  */
   uint32_t sz_v;  /* size of .v */
   uint64_t v;     /* value      */
@@ -119,13 +120,16 @@ TALER_PQ_make_taler_pq_amount_ (
  * @param oid_v OID of the INT8 type in postgres
  * @param oid_f OID of the INT4 type in postgres
  * @param oid_c OID of the TEXT type in postgres
+ * @param[out] rval set to encoded @a amount
+ * @return actual (useful) size of @a rval for Postgres
  */
-struct TALER_PQ_AmountCurrencyP
+size_t
 TALER_PQ_make_taler_pq_amount_currency_ (
   const struct TALER_Amount *amount,
   uint32_t oid_v,
   uint32_t oid_f,
-  uint32_t oid_c);
+  uint32_t oid_c,
+  struct TALER_PQ_AmountCurrencyP *rval);
 
 
 #endif  /* TALER_PQ_COMMON_H_ */
diff --git a/src/pq/pq_query_helper.c b/src/pq/pq_query_helper.c
index a1a1070b..48bbfb52 100644
--- a/src/pq/pq_query_helper.c
+++ b/src/pq/pq_query_helper.c
@@ -68,6 +68,7 @@ qconv_amount_currency_tuple (void *cls,
     Oid oid_v;
     Oid oid_f;
     Oid oid_c;
+    struct TALER_PQ_AmountCurrencyP d;
 
     GNUNET_assert (GNUNET_OK ==
                    GNUNET_PQ_get_oid_by_name (db,
@@ -79,24 +80,18 @@ qconv_amount_currency_tuple (void *cls,
                                               &oid_f));
     GNUNET_assert (GNUNET_OK ==
                    GNUNET_PQ_get_oid_by_name (db,
-                                              "text",
+                                              "varchar",
                                               &oid_c));
-
-    {
-      struct TALER_PQ_AmountCurrencyP d
-        = TALER_PQ_make_taler_pq_amount_currency_ (amount,
-                                                   oid_v,
-                                                   oid_f,
-                                                   oid_c);
-
-      sz = sizeof(uint32_t); /* number of elements in tuple */
-      sz += sizeof(d);
-      out = GNUNET_malloc (sz);
-      scratch[0] = out;
-      *(uint32_t *) out = htonl (3);
-      out += sizeof(uint32_t);
-      *(struct TALER_PQ_AmountCurrencyP*) out = d;
-    }
+    sz = TALER_PQ_make_taler_pq_amount_currency_ (amount,
+                                                  oid_v,
+                                                  oid_f,
+                                                  oid_c,
+                                                  &d);
+    out = GNUNET_malloc (sz);
+    memcpy (out,
+            &d,
+            sz);
+    scratch[0] = out;
   }
 
   param_values[0] = scratch[0];
diff --git a/src/pq/pq_result_helper.c b/src/pq/pq_result_helper.c
index 3befbdff..4b346e8a 100644
--- a/src/pq/pq_result_helper.c
+++ b/src/pq/pq_result_helper.c
@@ -79,43 +79,41 @@ extract_amount_currency_tuple (void *cls,
 
   /* Parse the tuple */
   {
-    char *in;
-    uint32_t num;
     struct TALER_PQ_AmountCurrencyP ap;
+    const char *in;
     int size;
-    const static int expected_size
-      = sizeof(uint32_t) /* length */
-        + sizeof(ap);
 
     size = PQgetlength (result,
                         row,
                         col);
-    if (expected_size != size)
+    if ( (size >= sizeof (ap)) ||
+         (size <= sizeof (ap) - TALER_CURRENCY_LEN) )
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Incorrect size of binary field `%s' (got %d, expected 
%d)\n",
+                  "Incorrect size of binary field `%s' (got %d, expected 
(%d-%d))\n",
                   fname,
                   size,
-                  expected_size);
+                  (int) (sizeof (ap) - TALER_CURRENCY_LEN),
+                  (int) sizeof (ap));
       return GNUNET_SYSERR;
     }
 
     in = PQgetvalue (result,
                      row,
                      col);
-
-    num = ntohl (*(uint32_t *) in);
-    if (3 != num)
+    memset (&ap.c,
+            0,
+            TALER_CURRENCY_LEN);
+    memcpy (&ap,
+            in,
+            size);
+    if (3 != 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);
@@ -224,7 +222,7 @@ extract_amount_tuple (void *cls,
 
   /* Parse the tuple */
   {
-    char *in;
+    const char *in;
     uint32_t num;
     struct TALER_PQ_AmountP ap;
     int size;

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]