diff options
| -rw-r--r-- | src/include/taler_json_lib.h | 14 | ||||
| -rw-r--r-- | src/json/json.c | 139 | 
2 files changed, 86 insertions, 67 deletions
| diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index a9829d4a..145a5d2e 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -191,9 +191,11 @@ TALER_JSON_spec_i18n_str (const char *name,   *   * @param[in] json some JSON value to hash   * @param[out] hc resulting hash code - * @return #GNUNET_OK on success, #GNUNET_SYSERR on error + * @return #GNUNET_OK on success, + *         #GNUNET_NO if @a json was malformed + *         #GNUNET_SYSERR on internal error   */ -int +enum GNUNET_GenericReturnValue  TALER_JSON_contract_hash (const json_t *json,                            struct GNUNET_HashCode *hc); @@ -207,7 +209,7 @@ TALER_JSON_contract_hash (const json_t *json,   * @param[in,out] json JSON to transform   * @return #GNUNET_OK on success   */ -int +enum GNUNET_GenericReturnValue  TALER_JSON_contract_seed_forgettable (json_t *json); @@ -218,7 +220,7 @@ TALER_JSON_contract_seed_forgettable (json_t *json);   * @param field name of the field to mark as forgettable   * @return #GNUNET_OK on success, #GNUNET_SYSERR on error   */ -int +enum GNUNET_GenericReturnValue  TALER_JSON_contract_mark_forgettable (json_t *json,                                        const char *field); @@ -232,7 +234,7 @@ TALER_JSON_contract_mark_forgettable (json_t *json,   *         #GNUNET_NO if the field was already forgotten before   *         #GNUNET_SYSERR on error   */ -int +enum GNUNET_GenericReturnValue  TALER_JSON_contract_part_forget (json_t *json,                                   const char *field); @@ -262,7 +264,7 @@ typedef void   * @param cb_cls closure for the callback.   * @return #GNUNET_OK on success, #GNUNET_SYSERR if @e path is invalid.   */ -int +enum GNUNET_GenericReturnValue  TALER_JSON_expand_path (json_t *json,                          const char *path,                          TALER_JSON_ExpandPathCallback cb, diff --git a/src/json/json.c b/src/json/json.c index fe2ea838..dbe13bbd 100644 --- a/src/json/json.c +++ b/src/json/json.c @@ -67,9 +67,11 @@ contains_real (const json_t *json)   * @param salt salt value to include when using HKDF,   *        NULL to not use any salt and to use SHA512   * @param[out] hc where to store the hash - * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure + * @return #GNUNET_OK on success, + *         #GNUNET_NO if @a json was not hash-able + *         #GNUNET_SYSERR on failure   */ -static int +static enum GNUNET_GenericReturnValue  dump_and_hash (const json_t *json,                 const char *salt,                 struct GNUNET_HashCode *hc) @@ -79,13 +81,13 @@ dump_and_hash (const json_t *json,    if (NULL == json)    { -    GNUNET_break (0); -    return GNUNET_SYSERR; +    GNUNET_break_op (0); +    return GNUNET_NO;    }    if (contains_real (json))    { -    GNUNET_break (0); -    return GNUNET_SYSERR; +    GNUNET_break_op (0); +    return GNUNET_NO;    }    if (NULL == (wire_enc = json_dumps (json,                                        JSON_ENCODE_ANY @@ -114,6 +116,7 @@ dump_and_hash (const json_t *json,                             NULL,                             0))      { +      GNUNET_break (0);        free (wire_enc);        return GNUNET_SYSERR;      } @@ -127,16 +130,20 @@ dump_and_hash (const json_t *json,   * Replace "forgettable" parts of a JSON object with their salted hash.   *   * @param[in] in some JSON value - * @return NULL on error + * @param[out] out resulting JSON value + * @return #GNUNET_OK on success, + *         #GNUNET_NO if @a json was not hash-able + *         #GNUNET_SYSERR on failure   */ -static json_t * -forget (const json_t *in) +static enum GNUNET_GenericReturnValue +forget (const json_t *in, +        json_t **out)  {    if (json_is_real (in))    {      /* floating point is not allowed! */ -    GNUNET_break (0); -    return NULL; +    GNUNET_break_op (0); +    return GNUNET_NO;    }    if (json_is_array (in))    { @@ -149,27 +156,29 @@ forget (const json_t *in)      if (NULL == ret)      {        GNUNET_break (0); -      return NULL; +      return GNUNET_SYSERR;      }      json_array_foreach (in, index, value) { +      enum GNUNET_GenericReturnValue iret;        json_t *t; -      t = forget (value); -      if (NULL == t) +      iret = forget (value, +                     &t); +      if (GNUNET_OK != iret)        { -        GNUNET_break (0);          json_decref (ret); -        return NULL; +        return iret;        }        if (0 != json_array_append_new (ret,                                        t))        {          GNUNET_break (0);          json_decref (ret); -        return NULL; +        return GNUNET_SYSERR;        }      } -    return ret; +    *out = ret; +    return GNUNET_OK;    }    if (json_is_object (in))    { @@ -184,18 +193,26 @@ forget (const json_t *in)      rx = json_object_get (in,                            "$forgotten");      if (NULL != rx) +    {        rx = json_deep_copy (rx); /* should be shallow                                     by structure, but                                     deep copy is safer */ +      if (NULL == rx) +      { +        GNUNET_break (0); +        return GNUNET_SYSERR; +      } +    }      ret = json_object ();      if (NULL == ret)      {        GNUNET_break (0); -      return NULL; +      return GNUNET_SYSERR;      }      json_object_foreach ((json_t*) in, key, value) {        json_t *t;        json_t *salt; +      enum GNUNET_GenericReturnValue iret;        if (fg == value)          continue; /* skip! */ @@ -210,13 +227,13 @@ forget (const json_t *in)                                  key);          continue; /* already forgotten earlier */        } -      t = forget (value); -      if (NULL == t) +      iret = forget (value, +                     &t); +      if (GNUNET_OK != iret)        { -        GNUNET_break (0);          json_decref (ret);          json_decref (rx); -        return NULL; +        return iret;        }        if ( (NULL != fg) &&             (NULL != (salt = json_object_get (fg, @@ -227,22 +244,21 @@ forget (const json_t *in)          if (! json_is_string (salt))          { -          GNUNET_break (0); +          GNUNET_break_op (0);            json_decref (ret);            json_decref (rx);            json_decref (t); -          return NULL; +          return GNUNET_NO;          } -        if (GNUNET_OK != -            dump_and_hash (t, -                           json_string_value (salt), -                           &hc)) +        iret = dump_and_hash (t, +                              json_string_value (salt), +                              &hc); +        if (GNUNET_OK != iret)          { -          GNUNET_break (0);            json_decref (ret);            json_decref (rx);            json_decref (t); -          return NULL; +          return iret;          }          json_decref (t);          /* scrub salt */ @@ -250,10 +266,10 @@ forget (const json_t *in)              json_object_del (fg,                               key))          { -          GNUNET_break (0); +          GNUNET_break_op (0);            json_decref (ret);            json_decref (rx); -          return NULL; +          return GNUNET_NO;          }          if (NULL == rx)            rx = json_object (); @@ -261,7 +277,7 @@ forget (const json_t *in)          {            GNUNET_break (0);            json_decref (ret); -          return NULL; +          return GNUNET_SYSERR;          }          if (0 !=              json_object_set_new (rx, @@ -271,7 +287,7 @@ forget (const json_t *in)            GNUNET_break (0);            json_decref (ret);            json_decref (rx); -          return NULL; +          return GNUNET_SYSERR;          }        }        else @@ -285,7 +301,7 @@ forget (const json_t *in)            GNUNET_break (0);            json_decref (ret);            json_decref (rx); -          return NULL; +          return GNUNET_SYSERR;          }        }      } /* json_object_foreach */ @@ -297,30 +313,30 @@ forget (const json_t *in)      {        GNUNET_break (0);        json_decref (ret); -      return NULL; +      return GNUNET_SYSERR;      } -    return ret; +    *out = ret; +    return GNUNET_OK;    } -  return json_incref ((json_t *) in); +  *out = json_incref ((json_t *) in); +  return GNUNET_OK;  } -int +enum GNUNET_GenericReturnValue  TALER_JSON_contract_hash (const json_t *json,                            struct GNUNET_HashCode *hc)  { -  int ret; +  enum GNUNET_GenericReturnValue ret;    json_t *cjson;    json_t *dc;    dc = json_deep_copy (json); -  cjson = forget (dc); +  ret = forget (dc, +                &cjson);    json_decref (dc); -  if (NULL == cjson) -  { -    GNUNET_break (0); -    return GNUNET_SYSERR; -  } +  if (GNUNET_OK != ret) +    return ret;    ret = dump_and_hash (cjson,                         NULL,                         hc); @@ -329,7 +345,7 @@ TALER_JSON_contract_hash (const json_t *json,  } -int +enum GNUNET_GenericReturnValue  TALER_JSON_contract_mark_forgettable (json_t *json,                                        const char *field)  { @@ -394,7 +410,7 @@ TALER_JSON_contract_mark_forgettable (json_t *json,  } -int +enum GNUNET_GenericReturnValue  TALER_JSON_contract_part_forget (json_t *json,                                   const char *field)  { @@ -404,6 +420,7 @@ TALER_JSON_contract_part_forget (json_t *json,    json_t *rx;    struct GNUNET_HashCode hc;    const char *salt; +  enum GNUNET_GenericReturnValue ret;    if (! json_is_object (json))    { @@ -469,12 +486,10 @@ TALER_JSON_contract_part_forget (json_t *json,    }    /* need to recursively forget to compute 'hc' */ -  fp = forget (part); -  if (NULL == fp) -  { -    GNUNET_break (0); -    return GNUNET_SYSERR; -  } +  ret = forget (part, +                &fp); +  if (GNUNET_OK != ret) +    return ret;    if (GNUNET_OK !=        dump_and_hash (fp,                       salt, @@ -524,7 +539,7 @@ TALER_JSON_contract_part_forget (json_t *json,   * @param[in,out] f JSON to transform   * @return #GNUNET_OK on success   */ -static int +static enum GNUNET_GenericReturnValue  seed_forgettable (json_t *f)  {    const char *key; @@ -566,7 +581,7 @@ seed_forgettable (json_t *f)   * @param[in,out] json JSON to transform   * @return #GNUNET_OK on success   */ -int +enum GNUNET_GenericReturnValue  TALER_JSON_contract_seed_forgettable (json_t *json)  {    if (json_is_object (json)) @@ -619,7 +634,7 @@ TALER_JSON_contract_seed_forgettable (json_t *json)   * @param cb_cls the closure for the callback.   * @return #GNUNET_OK on success, #GNUNET_SYSERR if @e path is malformed.   */ -static int +static enum GNUNET_GenericReturnValue  parse_path (json_t *obj,              json_t *prev,              const char *path, @@ -703,10 +718,12 @@ parse_path (json_t *obj,      else      {        unsigned int index; +      char dummy;        if (1 != sscanf (bracket, -                       "%u", -                       &index)) +                       "%u%c", +                       &index, +                       &dummy))        {          GNUNET_free (id);          GNUNET_free (next_path); @@ -740,7 +757,7 @@ parse_path (json_t *obj,  } -int +enum GNUNET_GenericReturnValue  TALER_JSON_expand_path (json_t *json,                          const char *path,                          TALER_JSON_ExpandPathCallback cb, | 
