gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: fix #6855


From: gnunet
Subject: [taler-exchange] branch master updated: fix #6855
Date: Sun, 09 May 2021 13:41:26 +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 684a2342 fix #6855
684a2342 is described below

commit 684a2342645f3b44b823a907f0309eb4fcfba50b
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sun May 9 13:41:23 2021 +0200

    fix #6855
---
 src/json/json.c      | 98 +++++++++++++++++++++++++++++++++++++++++++++++++---
 src/json/test_json.c | 69 ++++++++++++++++++++++++++++++++++++
 2 files changed, 163 insertions(+), 4 deletions(-)

diff --git a/src/json/json.c b/src/json/json.c
index e9fbb91f..4b91c0c5 100644
--- a/src/json/json.c
+++ b/src/json/json.c
@@ -17,6 +17,7 @@
  * @file json/json.c
  * @brief helper functions for JSON processing using libjansson
  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
+ * @author Christian Grothoff
  */
 #include "platform.h"
 #include <gnunet/gnunet_util_lib.h>
@@ -24,6 +25,41 @@
 #include "taler_json_lib.h"
 
 
+/**
+ * Check if @a json contains a 'real' value anywhere.
+ *
+ * @param json json to check
+ * @return true if a real is in it somewhere
+ */
+static bool
+contains_real (const json_t *json)
+{
+  if (json_is_real (json))
+    return true;
+  if (json_is_object (json))
+  {
+    json_t *member;
+    const char *name;
+
+    json_object_foreach ((json_t *) json, name, member)
+    if (contains_real (member))
+      return true;
+    return false;
+  }
+  if (json_is_array (json))
+  {
+    json_t *member;
+    size_t index;
+
+    json_array_foreach ((json_t *) json, index, member)
+    if (contains_real (member))
+      return true;
+    return false;
+  }
+  return false;
+}
+
+
 /**
  * Dump the @a json to a string and hash it.
  *
@@ -41,7 +77,16 @@ dump_and_hash (const json_t *json,
   char *wire_enc;
   size_t len;
 
-  GNUNET_break (NULL != json);
+  if (NULL == json)
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+  if (contains_real (json))
+  {
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
   if (NULL == (wire_enc = json_dumps (json,
                                       JSON_ENCODE_ANY
                                       | JSON_COMPACT
@@ -79,7 +124,7 @@ dump_and_hash (const json_t *json,
 
 
 /**
- * Replace "forgettable" parts of a JSON object with its salted hash.
+ * Replace "forgettable" parts of a JSON object with their salted hash.
  *
  * @param[in] in some JSON value
  * @return NULL on error
@@ -87,6 +132,12 @@ dump_and_hash (const json_t *json,
 static json_t *
 forget (const json_t *in)
 {
+  if (json_is_real (in))
+  {
+    /* floating point is not allowed! */
+    GNUNET_break (0);
+    return NULL;
+  }
   if (json_is_array (in))
   {
     /* array is a JSON array */
@@ -202,6 +253,16 @@ forget (const json_t *in)
           return NULL;
         }
         json_decref (t);
+        /* scrub salt */
+        if (0 !=
+            json_object_del (fg,
+                             key))
+        {
+          GNUNET_break (0);
+          json_decref (ret);
+          json_decref (rx);
+          return NULL;
+        }
         if (NULL == rx)
           rx = json_object ();
         if (NULL == rx)
@@ -268,8 +329,11 @@ TALER_JSON_contract_hash (const json_t *json,
 {
   int ret;
   json_t *cjson;
+  json_t *dc;
 
-  cjson = forget (json);
+  dc = json_deep_copy (json);
+  cjson = forget (dc);
+  json_decref (dc);
   if (NULL == cjson)
   {
     GNUNET_break (0);
@@ -295,9 +359,26 @@ TALER_JSON_contract_mark_forgettable (json_t *json,
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
+  /* check field name is legal for forgettable field */
+  for (const char *f = field; '\0' != *f; f++)
+  {
+    char c = *f;
+
+    if ( (c >= 'a') && (c <= 'z') )
+      continue;
+    if ( (c >= 'A') && (c <= 'Z') )
+      continue;
+    if ( (c >= '0') && (c <= '9') )
+      continue;
+    if ('_' == c)
+      continue;
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
   if (NULL == json_object_get (json,
                                field))
   {
+    /* field must exist */
     GNUNET_break (0);
     return GNUNET_SYSERR;
   }
@@ -335,7 +416,7 @@ int
 TALER_JSON_contract_part_forget (json_t *json,
                                  const char *field)
 {
-  const json_t *fg;
+  json_t *fg;
   const json_t *part;
   json_t *fp;
   json_t *rx;
@@ -391,6 +472,15 @@ TALER_JSON_contract_part_forget (json_t *json,
     return GNUNET_SYSERR;
   }
   json_decref (fp);
+  /* drop salt */
+  if (0 !=
+      json_object_del (fg,
+                       field))
+  {
+    json_decref (fp);
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
 
   rx = json_object_get (json,
                         "_forgotten");
diff --git a/src/json/test_json.c b/src/json/test_json.c
index 066ba4e7..21073d69 100644
--- a/src/json/test_json.c
+++ b/src/json/test_json.c
@@ -104,12 +104,49 @@ test_contract (void)
   GNUNET_assert (GNUNET_OK ==
                  TALER_JSON_contract_mark_forgettable (c1,
                                                        "k1"));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_JSON_contract_mark_forgettable (c1,
+                                                       "k2"));
   GNUNET_assert (GNUNET_OK ==
                  TALER_JSON_contract_hash (c1,
                                            &h1));
   GNUNET_assert (GNUNET_OK ==
                  TALER_JSON_contract_part_forget (c1,
                                                   "k1"));
+  /* check salt was forgotten */
+  GNUNET_assert (NULL ==
+                 json_object_get (json_object_get (c1,
+                                                   "_forgettable"),
+                                  "k1"));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_JSON_contract_hash (c1,
+                                           &h2));
+  if (0 !=
+      GNUNET_memcmp (&h1,
+                     &h2))
+  {
+    GNUNET_break (0);
+    json_decref (c1);
+    return 1;
+  }
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_JSON_contract_part_forget (json_object_get (c1,
+                                                                   "k2"),
+                                                  "n1"));
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_JSON_contract_hash (c1,
+                                           &h2));
+  if (0 !=
+      GNUNET_memcmp (&h1,
+                     &h2))
+  {
+    GNUNET_break (0);
+    json_decref (c1);
+    return 1;
+  }
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_JSON_contract_part_forget (c1,
+                                                  "k2"));
   GNUNET_assert (GNUNET_OK ==
                  TALER_JSON_contract_hash (c1,
                                            &h2));
@@ -121,6 +158,38 @@ test_contract (void)
     GNUNET_break (0);
     return 1;
   }
+
+
+  c1 = json_pack ("{s:I, s:{s:s}, s:{s:b, s:{s:s}}, s:{s:s}}",
+                  "k1", 1,
+                  "_forgettable", "k1", "SALT",
+                  "k2", "n1", true,
+                  /***/ "_forgettable", "n1", "salt",
+                  "k3", "n1", "string");
+  GNUNET_assert (GNUNET_OK ==
+                 TALER_JSON_contract_hash (c1,
+                                           &h1));
+  json_dumpf (c1, stderr, JSON_INDENT (2));
+  json_decref (c1);
+  {
+    char *s;
+
+    s = GNUNET_STRINGS_data_to_string_alloc (&h1,
+                                             sizeof (h1));
+    if (0 !=
+        strcmp (s,
+                
"287VXK8T6PXKD05W8Y94QJNEFCMRXBC9S7KNKTWGH2G2J2D7RYKPSHNH1HG9NT1K2HRHGC67W6QM6GEC4BSN1DPNEBCS0AVDT2DBP5G"))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  "Invalid reference hash: %s\n",
+                  s);
+      GNUNET_free (s);
+      return 1;
+    }
+    GNUNET_free (s);
+  }
+
+
   c2 = json_pack ("{s:s}",
                   "n1", "n2");
   GNUNET_assert (NULL != c2);

-- 
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]