fix #6855
This commit is contained in:
parent
6ee58c990c
commit
684a234264
@ -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");
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user