summaryrefslogtreecommitdiff
path: root/src/json
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-07-05 21:54:11 +0200
committerChristian Grothoff <christian@grothoff.org>2020-07-05 21:54:11 +0200
commit54e63f01df85ee0470493c6d0de29576ce3371c4 (patch)
tree174ef13378081c4845a9f0adc52bcac97674aff2 /src/json
parent6de49ea2c02e311e5f5366005bd3497a9bb25187 (diff)
downloadexchange-54e63f01df85ee0470493c6d0de29576ce3371c4.tar.gz
exchange-54e63f01df85ee0470493c6d0de29576ce3371c4.tar.bz2
exchange-54e63f01df85ee0470493c6d0de29576ce3371c4.zip
fix #6408: make sure all timestamps are always rounded when they arrive over JSON, or 400 the requester; similarly don't tolerate anything else as client
Diffstat (limited to 'src/json')
-rw-r--r--src/json/json_helper.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
index 746b39e49..44eeb87bf 100644
--- a/src/json/json_helper.c
+++ b/src/json/json_helper.c
@@ -175,6 +175,147 @@ TALER_JSON_spec_amount_nbo (const char *name,
/**
+ * Parse given JSON object to *rounded* absolute time.
+ *
+ * @param cls closure, NULL
+ * @param root the json object representing data
+ * @param[out] spec where to write the data
+ * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+ */
+static int
+parse_abs_time (void *cls,
+ json_t *root,
+ struct GNUNET_JSON_Specification *spec)
+{
+ struct GNUNET_TIME_Absolute *abs = spec->ptr;
+ json_t *json_t_ms;
+ unsigned long long int tval;
+
+ if (! json_is_object (root))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ json_t_ms = json_object_get (root, "t_ms");
+ if (json_is_integer (json_t_ms))
+ {
+ tval = json_integer_value (json_t_ms);
+ /* Time is in milliseconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
+ abs->abs_value_us = tval * 1000LL;
+ if ((abs->abs_value_us) / 1000LL != tval)
+ {
+ /* Integer overflow */
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ if (GNUNET_OK !=
+ GNUNET_TIME_round_abs (abs))
+ {
+ /* time not rounded */
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+ }
+ if (json_is_string (json_t_ms))
+ {
+ const char *val;
+ val = json_string_value (json_t_ms);
+ if ((0 == strcasecmp (val, "never")))
+ {
+ *abs = GNUNET_TIME_UNIT_FOREVER_ABS;
+ return GNUNET_OK;
+ }
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+}
+
+
+/**
+ * Provide specification to parse given JSON object to an absolute time.
+ * The absolute time value is expected to be already rounded.
+ *
+ * @param name name of the time field in the JSON
+ * @param[out] r_time where the time has to be written
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_absolute_time (const char *name,
+ struct GNUNET_TIME_Absolute *r_time)
+{
+ struct GNUNET_JSON_Specification ret = {
+ .parser = &parse_abs_time,
+ .cleaner = NULL,
+ .cls = NULL,
+ .field = name,
+ .ptr = r_time,
+ .ptr_size = sizeof(uint64_t),
+ .size_ptr = NULL
+ };
+
+ return ret;
+}
+
+
+/**
+ * Parse given JSON object to absolute time.
+ *
+ * @param cls closure, NULL
+ * @param root the json object representing data
+ * @param[out] spec where to write the data
+ * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
+ */
+static int
+parse_abs_time_nbo (void *cls,
+ json_t *root,
+ struct GNUNET_JSON_Specification *spec)
+{
+ struct GNUNET_TIME_AbsoluteNBO *abs = spec->ptr;
+ struct GNUNET_TIME_Absolute a;
+ struct GNUNET_JSON_Specification ispec;
+
+ ispec = *spec;
+ ispec.parser = &parse_abs_time;
+ ispec.ptr = &a;
+ if (GNUNET_OK !=
+ parse_abs_time (NULL,
+ root,
+ &ispec))
+ return GNUNET_SYSERR;
+ *abs = GNUNET_TIME_absolute_hton (a);
+ return GNUNET_OK;
+}
+
+
+/**
+ * Provide specification to parse given JSON object to an absolute time
+ * in network byte order.
+ * The absolute time value is expected to be already rounded.
+ *
+ * @param name name of the time field in the JSON
+ * @param[out] r_time where the time has to be written
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_absolute_time_nbo (const char *name,
+ struct GNUNET_TIME_AbsoluteNBO *r_time)
+{
+ struct GNUNET_JSON_Specification ret = {
+ .parser = &parse_abs_time_nbo,
+ .cleaner = NULL,
+ .cls = NULL,
+ .field = name,
+ .ptr = r_time,
+ .ptr_size = sizeof(uint64_t),
+ .size_ptr = NULL
+ };
+
+ return ret;
+}
+
+
+/**
* Generate line in parser specification for denomination public key.
*
* @param field name of the field