From 3bb26bcf47e4f58df53addb70fdeeefbabd2e8be Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 20 Jun 2015 22:53:01 +0200 Subject: deduplicate code with util/json.c, do use consistently /time/ encoding --- src/mint-lib/mint_api_handle.c | 3 + src/mint-lib/mint_api_json.c | 132 +++++------------------------------------ src/util/json.c | 100 +++++++++++++++++++++---------- 3 files changed, 87 insertions(+), 148 deletions(-) (limited to 'src') diff --git a/src/mint-lib/mint_api_handle.c b/src/mint-lib/mint_api_handle.c index 8a5212ae5..9d6c4b0a0 100644 --- a/src/mint-lib/mint_api_handle.c +++ b/src/mint-lib/mint_api_handle.c @@ -355,7 +355,10 @@ parse_json_denomkey (struct TALER_MINT_DenomPublicKey *denom_key, if (GNUNET_OK != MAJ_parse_json (denom_key_obj, spec)) + { + GNUNET_break_op (0); return GNUNET_SYSERR; + } memset (&denom_key_issue, 0, sizeof (denom_key_issue)); GNUNET_CRYPTO_rsa_public_key_hash (pk, diff --git a/src/mint-lib/mint_api_json.c b/src/mint-lib/mint_api_json.c index 75010a4d1..b702ba0d9 100644 --- a/src/mint-lib/mint_api_json.c +++ b/src/mint-lib/mint_api_json.c @@ -24,116 +24,6 @@ #include "mint_api_json.h" -/** - * Parse absolute time specified in JSON format. The JSON format is - * "/TIMEVAL/" where TIMEVAL is in milliseconds. Additionally, we - * support "/forever/" to represent the end of time. - * - * @param f json specification of the amount - * @param[out] time set to the time specified in @a f - * @return - * #GNUNET_YES if parsing was successful - * #GNUNET_SYSERR on errors - */ -static int -parse_time_abs (json_t *f, - struct GNUNET_TIME_Absolute *time) -{ - const char *val; - size_t slen; - unsigned long long int tval; - char *endp; - - val = json_string_value (f); - if (NULL == val) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - slen = strlen (val); - if ( (slen <= 2) || - ('/' != val[0]) || - ('/' != val[slen - 1]) ) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (0 == strcasecmp (val, - "/forever/")) - { - *time = GNUNET_TIME_UNIT_FOREVER_ABS; - return GNUNET_OK; - } - tval = strtoull (&val[1], - &endp, - 10); - if (&val[slen - 1] != endp) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */ - time->abs_value_us = tval * 1000LL * 1000LL; - if ( (time->abs_value_us) / 1000LL / 1000LL != tval) - { - /* Integer overflow */ - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - return GNUNET_OK; -} - - -/** - * Parse amount specified in JSON format. - * - * @param f json specification of the amount - * @param[out] amount set to the amount specified in @a f - * @return - * #GNUNET_OK if parsing was successful - * #GNUNET_SYSERR on error - */ -static int -parse_amount (json_t *f, - struct TALER_Amount *amount) -{ - json_int_t value; - json_int_t fraction; - const char *currency; - - memset (amount, - 0, - sizeof (struct TALER_Amount)); - if (-1 == json_unpack (f, - "{s:I, s:I, s:s}", - "value", &value, - "fraction", &fraction, - "currency", ¤cy)) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if ( (value < 0) || - (fraction < 0) || - (value > UINT64_MAX) || - (fraction > UINT32_MAX) ) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - if (strlen (currency) >= TALER_CURRENCY_LEN) - { - GNUNET_break_op (0); - return GNUNET_SYSERR; - } - amount->value = (uint64_t) value; - amount->fraction = (uint32_t) fraction; - strcpy (amount->currency, currency); - (void) TALER_amount_normalize (amount); - return GNUNET_OK; -} - - /** * Navigate and parse data in a JSON tree. * @@ -165,15 +55,21 @@ parse_json (json_t *root, return i; case MAJ_CMD_AMOUNT: if (GNUNET_OK != - parse_amount (pos, - spec[i].details.amount)) + TALER_json_to_amount (pos, + spec[i].details.amount)) + { + GNUNET_break_op (0); return i; + } break; case MAJ_CMD_TIME_ABSOLUTE: if (GNUNET_OK != - parse_time_abs (pos, - spec[i].details.abs_time)) + TALER_json_to_abs (pos, + spec[i].details.abs_time)) + { + GNUNET_break_op (0); return i; + } break; case MAJ_CMD_BINARY_FIXED: @@ -240,7 +136,7 @@ parse_json (json_t *root, int res; void *buf; - str = json_string_value (root); + str = json_string_value (pos); if (NULL == str) { GNUNET_break_op (0); @@ -277,7 +173,7 @@ parse_json (json_t *root, int res; void *buf; - str = json_string_value (root); + str = json_string_value (pos); if (NULL == str) { GNUNET_break_op (0); @@ -454,7 +350,7 @@ MAJ_spec_rsa_public_key (const char *name, { struct MAJ_Specification ret = { - .cmd = MAJ_CMD_AMOUNT, + .cmd = MAJ_CMD_RSA_PUBLIC_KEY, .field = name, .details.rsa_public_key = pk }; @@ -474,7 +370,7 @@ MAJ_spec_rsa_signature (const char *name, { struct MAJ_Specification ret = { - .cmd = MAJ_CMD_AMOUNT, + .cmd = MAJ_CMD_RSA_SIGNATURE, .field = name, .details.rsa_signature = sig }; diff --git a/src/util/json.c b/src/util/json.c index d72840ebe..17eb0f3fd 100644 --- a/src/util/json.c +++ b/src/util/json.c @@ -90,7 +90,7 @@ TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp) int ret; if (stamp.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us) - return json_string ("never"); + return json_string ("/never/"); ret = GNUNET_asprintf (&mystr, "/%llu/", (long long) (stamp.abs_value_us / (1000LL * 1000LL))); @@ -282,28 +282,40 @@ int TALER_json_to_amount (json_t *json, struct TALER_Amount *r_amount) { - char *currency; json_int_t value; json_int_t fraction; - json_error_t error; - - UNPACK_EXITIF (0 != json_unpack_ex (json, - &error, - JSON_STRICT, - "{s:s, s:I, s:I}", - "currency", ¤cy, - "value", &value, - "fraction", &fraction)); - EXITIF (3 < strlen (currency)); - EXITIF (TALER_CURRENCY_LEN <= strlen (currency)); - strcpy (r_amount->currency, - currency); - r_amount->value = (uint32_t) value; + const char *currency; + + memset (r_amount, + 0, + sizeof (struct TALER_Amount)); + if (-1 == json_unpack (json, + "{s:I, s:I, s:s}", + "value", &value, + "fraction", &fraction, + "currency", ¤cy)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + if ( (value < 0) || + (fraction < 0) || + (value > UINT64_MAX) || + (fraction > UINT32_MAX) ) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + if (strlen (currency) >= TALER_CURRENCY_LEN) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + r_amount->value = (uint64_t) value; r_amount->fraction = (uint32_t) fraction; + strcpy (r_amount->currency, currency); + (void) TALER_amount_normalize (r_amount); return GNUNET_OK; - - EXITIF_exit: - return GNUNET_SYSERR; } @@ -318,25 +330,53 @@ int TALER_json_to_abs (json_t *json, struct GNUNET_TIME_Absolute *abs) { - const char *str; - unsigned long long abs_value_s; + const char *val; + size_t slen; + unsigned long long int tval; + char *endp; - GNUNET_assert (NULL != abs); - EXITIF (NULL == (str = json_string_value (json))); - if (0 == strcasecmp (str, - "never")) + val = json_string_value (json); + if (NULL == val) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + slen = strlen (val); + if ( (slen <= 2) || + ('/' != val[0]) || + ('/' != val[slen - 1]) ) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + if ( (0 == strcasecmp (val, + "/forever/")) || + (0 == strcasecmp (val, + "/never/")) ) { *abs = GNUNET_TIME_UNIT_FOREVER_ABS; return GNUNET_OK; } - EXITIF (1 > sscanf (str, "%llu", &abs_value_s)); - abs->abs_value_us = abs_value_s * 1000LL * 1000LL; + tval = strtoull (&val[1], + &endp, + 10); + if (&val[slen - 1] != endp) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */ + abs->abs_value_us = tval * 1000LL * 1000LL; + if ( (abs->abs_value_us) / 1000LL / 1000LL != tval) + { + /* Integer overflow */ + GNUNET_break_op (0); + return GNUNET_SYSERR; + } return GNUNET_OK; - - EXITIF_exit: - return GNUNET_SYSERR; } + /** * Parse given JSON object to data * -- cgit v1.2.3