trying to fix #7039 insanity for RFC 8785, Dold: please check
This commit is contained in:
parent
a5a3b2ea9a
commit
ae2ce4aaee
@ -411,6 +411,7 @@ stop_fakebank (void *cls)
|
||||
static void
|
||||
never_task (void *cls)
|
||||
{
|
||||
(void) cls;
|
||||
GNUNET_assert (0);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ libtalerjson_la_LIBADD = \
|
||||
$(top_builddir)/src/util/libtalerutil.la \
|
||||
-lgnunetjson \
|
||||
-lgnunetutil \
|
||||
-lunistring \
|
||||
-ljansson \
|
||||
-lm \
|
||||
$(XLIB)
|
||||
|
158
src/json/json.c
158
src/json/json.c
@ -23,6 +23,7 @@
|
||||
#include <gnunet/gnunet_util_lib.h>
|
||||
#include "taler_util.h"
|
||||
#include "taler_json_lib.h"
|
||||
#include <unistr.h>
|
||||
|
||||
|
||||
/**
|
||||
@ -60,6 +61,161 @@ contains_real (const json_t *json)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dump character in the low range into @a buf
|
||||
* following RFC 8785.
|
||||
*
|
||||
* @param[in,out] buf buffer to modify
|
||||
* @param val value to dump
|
||||
*/
|
||||
static void
|
||||
lowdump (struct GNUNET_Buffer *buf,
|
||||
unsigned char val)
|
||||
{
|
||||
char scratch[7];
|
||||
|
||||
switch (val)
|
||||
{
|
||||
case 0x8:
|
||||
GNUNET_buffer_write (buf,
|
||||
"\b",
|
||||
2);
|
||||
break;
|
||||
case 0x9:
|
||||
GNUNET_buffer_write (buf,
|
||||
"\t",
|
||||
2);
|
||||
break;
|
||||
case 0xA:
|
||||
GNUNET_buffer_write (buf,
|
||||
"\n",
|
||||
2);
|
||||
break;
|
||||
case 0xC:
|
||||
GNUNET_buffer_write (buf,
|
||||
"\f",
|
||||
2);
|
||||
break;
|
||||
case 0xD:
|
||||
GNUNET_buffer_write (buf,
|
||||
"\r",
|
||||
2);
|
||||
break;
|
||||
default:
|
||||
GNUNET_snprintf (scratch,
|
||||
sizeof (scratch),
|
||||
"\\u%04x",
|
||||
(unsigned int) val);
|
||||
GNUNET_buffer_write (buf,
|
||||
scratch,
|
||||
6);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Re-encode string at @a inp to match RFC 8785 (section 3.2.2.2).
|
||||
*
|
||||
* @param[in,out] inp pointer to string to re-encode
|
||||
* @return number of bytes in resulting @a inp
|
||||
*/
|
||||
static size_t
|
||||
rfc8785encode (char **inp)
|
||||
{
|
||||
struct GNUNET_Buffer buf = { 0 };
|
||||
size_t left = strlen (*inp) + 1;
|
||||
size_t olen;
|
||||
char *in = *inp;
|
||||
const char *pos = in;
|
||||
|
||||
GNUNET_buffer_prealloc (&buf,
|
||||
left + 40);
|
||||
buf.warn_grow = 0; /* disable, + 40 is just a wild guess */
|
||||
while (1)
|
||||
{
|
||||
int mbl = u8_mblen ((unsigned char *) pos,
|
||||
left);
|
||||
unsigned char val;
|
||||
|
||||
if (0 == mbl)
|
||||
break;
|
||||
val = (unsigned char) *pos;
|
||||
if ( (1 == mbl) &&
|
||||
(val <= 0x1F) )
|
||||
{
|
||||
lowdump (&buf,
|
||||
val);
|
||||
}
|
||||
else if ( (1 == mbl) && ('\\' == *pos) )
|
||||
{
|
||||
switch (*(pos + 1))
|
||||
{
|
||||
case '\\':
|
||||
mbl = 2;
|
||||
GNUNET_buffer_write (&buf,
|
||||
pos,
|
||||
mbl);
|
||||
break;
|
||||
case 'u':
|
||||
{
|
||||
unsigned int num;
|
||||
uint32_t n32;
|
||||
unsigned char res[8];
|
||||
size_t rlen;
|
||||
|
||||
GNUNET_assert ( (1 ==
|
||||
sscanf (pos + 2,
|
||||
"%4x",
|
||||
&num)) ||
|
||||
(1 ==
|
||||
sscanf (pos + 2,
|
||||
"%4X",
|
||||
&num)) );
|
||||
mbl = 6;
|
||||
n32 = (uint32_t) num;
|
||||
rlen = sizeof (res);
|
||||
u32_to_u8 (&n32,
|
||||
1,
|
||||
res,
|
||||
&rlen);
|
||||
if ( (1 == rlen) &&
|
||||
(res[0] <= 0x1F) )
|
||||
{
|
||||
lowdump (&buf,
|
||||
res[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
GNUNET_buffer_write (&buf,
|
||||
(const char *) res,
|
||||
rlen);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GNUNET_buffer_write (&buf,
|
||||
pos,
|
||||
mbl);
|
||||
}
|
||||
left -= mbl;
|
||||
pos += mbl;
|
||||
}
|
||||
|
||||
/* 0-terminate buffer */
|
||||
GNUNET_buffer_write (&buf,
|
||||
"",
|
||||
1);
|
||||
GNUNET_free (in);
|
||||
*inp = GNUNET_buffer_reap (&buf,
|
||||
&olen);
|
||||
return olen;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dump the @a json to a string and hash it.
|
||||
*
|
||||
@ -97,7 +253,7 @@ dump_and_hash (const json_t *json,
|
||||
GNUNET_break (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
len = strlen (wire_enc) + 1;
|
||||
len = rfc8785encode (&wire_enc);
|
||||
if (NULL == salt)
|
||||
{
|
||||
GNUNET_CRYPTO_hash (wire_enc,
|
||||
|
@ -330,6 +330,40 @@ test_contract (void)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
test_rfc8785 (void)
|
||||
{
|
||||
struct TALER_PrivateContractHash h1;
|
||||
json_t *c1;
|
||||
|
||||
c1 = json_pack ("{s:s}",
|
||||
"k1", "\x08\x0B\t\1\\\x0d");
|
||||
GNUNET_assert (GNUNET_OK ==
|
||||
TALER_JSON_contract_hash (c1,
|
||||
&h1));
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = GNUNET_STRINGS_data_to_string_alloc (&h1,
|
||||
sizeof (h1));
|
||||
if (0 !=
|
||||
strcmp (s,
|
||||
"J678K3PW9Y3DG63Z3T7ZYR2P7CEXMVZ2SFPQMABACK9TJRYREPP82542PCJ0P7Y7FAQAMWECDX50XH1RBTWHX6SSJHH6FXRV0JCS6R8"))
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Invalid reference hash: %s\n",
|
||||
s);
|
||||
GNUNET_free (s);
|
||||
json_decref (c1);
|
||||
return 1;
|
||||
}
|
||||
GNUNET_free (s);
|
||||
}
|
||||
json_decref (c1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
const char *const argv[])
|
||||
@ -343,6 +377,8 @@ main (int argc,
|
||||
return 1;
|
||||
if (0 != test_contract ())
|
||||
return 2;
|
||||
if (0 != test_rfc8785 ())
|
||||
return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user