aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-01-16 15:04:47 +0100
committerChristian Grothoff <christian@grothoff.org>2015-01-16 15:04:47 +0100
commit7fe250407c440e59bece248747ffe8b29a8833b3 (patch)
treea662277cbce80249ddf8b3fef9e129d5dff7e8fd
parent4bd515191b6db342ff465e0595cfeafe6da8a680 (diff)
downloadexchange-7fe250407c440e59bece248747ffe8b29a8833b3.tar.gz
exchange-7fe250407c440e59bece248747ffe8b29a8833b3.tar.bz2
exchange-7fe250407c440e59bece248747ffe8b29a8833b3.zip
clean up (and rename) request_json_require_nav to properly report parsing errors
-rw-r--r--src/mint/taler-mint-httpd_deposit.c7
-rw-r--r--src/mint/taler-mint-httpd_parsing.c156
-rw-r--r--src/mint/taler-mint-httpd_parsing.h80
-rw-r--r--src/mint/taler-mint-httpd_refresh.c36
4 files changed, 151 insertions, 128 deletions
diff --git a/src/mint/taler-mint-httpd_deposit.c b/src/mint/taler-mint-httpd_deposit.c
index d92dd5ef7..eaced51c2 100644
--- a/src/mint/taler-mint-httpd_deposit.c
+++ b/src/mint/taler-mint-httpd_deposit.c
@@ -131,9 +131,10 @@ TALER_MINT_handler_deposit (struct RequestHandler *rh,
if (cond) { GNUNET_break (0); goto EXITIF_exit; } \
} while (0)
#define PARSE_DATA(field, addr) \
- EXITIF (GNUNET_OK != request_json_require_nav \
- (connection, json, \
- JNAV_FIELD, field, JNAV_RET_DATA, addr, sizeof (*addr)))
+ EXITIF (GNUNET_OK != \
+ GNUNET_MINT_parse_navigate_json \
+ (connection, json, \
+ JNAV_FIELD, field, JNAV_RET_DATA, addr, sizeof (*addr)))
PARSE_DATA ("coin_pub", &deposit->coin_pub);
PARSE_DATA ("denom_pub", &deposit->denom_pub);
PARSE_DATA ("ubsig", &ubsig);
diff --git a/src/mint/taler-mint-httpd_parsing.c b/src/mint/taler-mint-httpd_parsing.c
index 19c88d456..7d3f3b5e6 100644
--- a/src/mint/taler-mint-httpd_parsing.c
+++ b/src/mint/taler-mint-httpd_parsing.c
@@ -271,44 +271,48 @@ TALER_MINT_parse_post_cleanup_callback (void *con_cls)
* @param ... navigation specification (see JNAV_*)
* @return GNUNET_YES if navigation was successful
* GNUNET_NO if json is malformed, error response was generated
- * GNUNET_SYSERR on internal error
+ * GNUNET_SYSERR on internal error (no response was generated,
+ * connection must be closed)
*/
int
-request_json_require_nav (struct MHD_Connection *connection,
- const json_t *root, ...)
+GNUNET_MINT_parse_navigate_json (struct MHD_Connection *connection,
+ const json_t *root,
+ ...)
{
va_list argp;
- int ignore = GNUNET_NO;
- // what's our current path from 'root'?
- json_t *path;
+ int ret;
+ json_t *path; /* what's our current path from 'root'? */
path = json_array ();
-
- va_start(argp, root);
-
- while (1)
+ va_start (argp, root);
+ ret = 2;
+ while (2 == ret)
{
- int command = va_arg(argp, int);
+ enum TALER_MINT_JsonNavigationCommand command
+ = va_arg (argp,
+ enum TALER_MINT_JsonNavigationCommand);
+
switch (command)
{
case JNAV_FIELD:
{
const char *fname = va_arg(argp, const char *);
- if (GNUNET_YES == ignore)
- break;
- json_array_append_new (path, json_string (fname));
- root = json_object_get (root, fname);
+
+ json_array_append_new (path,
+ json_string (fname));
+ root = json_object_get (root,
+ fname);
if (NULL == root)
{
- /* FIXME: can't IGNORE this return value! */
- (void) TALER_MINT_reply_json_pack (connection,
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s,s:o}",
"error",
"missing field in JSON",
"path",
- path);
- ignore = GNUNET_YES;
+ path))
+ ? GNUNET_NO : GNUNET_SYSERR;
break;
}
}
@@ -316,19 +320,21 @@ request_json_require_nav (struct MHD_Connection *connection,
case JNAV_INDEX:
{
int fnum = va_arg(argp, int);
- if (GNUNET_YES == ignore)
- break;
- json_array_append_new (path, json_integer (fnum));
- root = json_array_get (root, fnum);
+
+ json_array_append_new (path,
+ json_integer (fnum));
+ root = json_array_get (root,
+ fnum);
if (NULL == root)
{
- /* FIXME: can't IGNORE this return value! */
- (void) TALER_MINT_reply_json_pack (connection,
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:o}",
- "error", "missing index in JSON",
- "path", path);
- ignore = GNUNET_YES;
+ "error",
+ "missing index in JSON",
+ "path", path))
+ ? GNUNET_NO : GNUNET_SYSERR;
break;
}
}
@@ -340,36 +346,36 @@ request_json_require_nav (struct MHD_Connection *connection,
const char *str;
int res;
- va_end(argp);
- if (GNUNET_YES == ignore)
- return GNUNET_NO;
str = json_string_value (root);
if (NULL == str)
{
- /* FIXME: can't IGNORE this return value! */
- (void) TALER_MINT_reply_json_pack (connection,
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:o}",
"error",
"string expected",
"path",
- path);
- return GNUNET_NO;
+ path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
}
res = GNUNET_STRINGS_string_to_data (str, strlen (str),
where, len);
if (GNUNET_OK != res)
{
- /* FIXME: can't IGNORE this return value! */
- (void) TALER_MINT_reply_json_pack (connection,
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s,s:o}",
"error",
"malformed binary data in JSON",
- "path", path);
- return GNUNET_NO;
+ "path",
+ path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
}
- return GNUNET_YES;
+ ret = GNUNET_OK;
}
break;
case JNAV_RET_DATA_VAR:
@@ -378,35 +384,42 @@ request_json_require_nav (struct MHD_Connection *connection,
size_t *len = va_arg (argp, size_t *);
const char *str;
- va_end(argp);
- if (GNUNET_YES == ignore)
- return GNUNET_NO;
str = json_string_value (root);
if (NULL == str)
{
- GNUNET_break (0);
- return GNUNET_SYSERR;
+ ret = (MHD_YES ==
+ TALER_MINT_reply_internal_error (connection,
+ "json_string_value() failed"))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
}
*len = (strlen (str) * 5) / 8;
- if (where != NULL)
+ if (NULL != where)
{
int res;
+
*where = GNUNET_malloc (*len);
- res = GNUNET_STRINGS_string_to_data (str, strlen (str),
- *where, *len);
+ res = GNUNET_STRINGS_string_to_data (str,
+ strlen (str),
+ *where,
+ *len);
if (GNUNET_OK != res)
{
- /* FIXME: can't IGNORE this return value! */
- (void) TALER_MINT_reply_json_pack (connection,
+ GNUNET_free (*where);
+ *where = NULL;
+ *len = 0;
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
MHD_HTTP_BAD_REQUEST,
"{s:s, s:o}",
"error",
"malformed binary data in JSON",
- "path", path);
- return GNUNET_NO;
+ "path", path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
}
}
- return GNUNET_OK;
+ ret = GNUNET_OK;
}
break;
case JNAV_RET_TYPED_JSON:
@@ -414,30 +427,35 @@ request_json_require_nav (struct MHD_Connection *connection,
int typ = va_arg (argp, int);
const json_t **r_json = va_arg (argp, const json_t **);
- va_end(argp);
- if (GNUNET_YES == ignore)
- return GNUNET_NO;
- if (typ != -1 && json_typeof (root) != typ)
+ if ( (-1 != typ) && (json_typeof (root) != typ))
{
- /* FIXME: can't IGNORE this return value! */
- (void) TALER_MINT_reply_json_pack (connection,
- MHD_HTTP_BAD_REQUEST,
- "{s:s, s:i, s:i s:o}",
- "error", "wrong JSON field type",
- "type_expected", typ,
- "type_actual", json_typeof (root),
- "path", path);
- return GNUNET_NO;
+ ret = (MHD_YES ==
+ TALER_MINT_reply_json_pack (connection,
+ MHD_HTTP_BAD_REQUEST,
+ "{s:s, s:i, s:i s:o}",
+ "error", "wrong JSON field type",
+ "type_expected", typ,
+ "type_actual", json_typeof (root),
+ "path", path))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
}
*r_json = root;
- return GNUNET_OK;
+ ret = GNUNET_OK;
}
break;
default:
- GNUNET_assert (0);
+ GNUNET_break (0);
+ ret = (MHD_YES ==
+ TALER_MINT_reply_internal_error (connection,
+ "unhandled value in switch"))
+ ? GNUNET_NO : GNUNET_SYSERR;
+ break;
}
}
- GNUNET_assert (0);
+ va_end (argp);
+ json_decref (path);
+ return ret;
}
diff --git a/src/mint/taler-mint-httpd_parsing.h b/src/mint/taler-mint-httpd_parsing.h
index c725187c5..a03f2b62d 100644
--- a/src/mint/taler-mint-httpd_parsing.h
+++ b/src/mint/taler-mint-httpd_parsing.h
@@ -31,43 +31,6 @@
/**
- * Constants for JSON navigation description.
- */
-enum
-{
- /**
- * Access a field.
- * Param: const char *
- */
- JNAV_FIELD,
- /**
- * Access an array index.
- * Param: int
- */
- JNAV_INDEX,
- /**
- * Return base32crockford encoded data of
- * constant size.
- * Params: (void *, size_t)
- */
- JNAV_RET_DATA,
- /**
- * Return base32crockford encoded data of
- * variable size.
- * Params: (void **, size_t *)
- */
- JNAV_RET_DATA_VAR,
- /**
- * Return a json object, which must be
- * of the given type (JSON_* type constants,
- * or -1 for any type).
- * Params: (int, json_t **)
- */
- JNAV_RET_TYPED_JSON
-};
-
-
-/**
* Process a POST request containing a JSON object. This
* function realizes an MHD POST processor that will
* (incrementally) process JSON data uploaded to the HTTP
@@ -111,6 +74,47 @@ TALER_MINT_parse_post_cleanup_callback (void *con_cls);
/**
+ * Constants for JSON navigation description.
+ */
+enum TALER_MINT_JsonNavigationCommand
+{
+ /**
+ * Access a field.
+ * Param: const char *
+ */
+ JNAV_FIELD,
+
+ /**
+ * Access an array index.
+ * Param: int
+ */
+ JNAV_INDEX,
+
+ /**
+ * Return base32crockford encoded data of
+ * constant size.
+ * Params: (void *, size_t)
+ */
+ JNAV_RET_DATA,
+
+ /**
+ * Return base32crockford encoded data of
+ * variable size.
+ * Params: (void **, size_t *)
+ */
+ JNAV_RET_DATA_VAR,
+
+ /**
+ * Return a json object, which must be
+ * of the given type (JSON_* type constants,
+ * or -1 for any type).
+ * Params: (int, json_t **)
+ */
+ JNAV_RET_TYPED_JSON
+};
+
+
+/**
* Navigate through a JSON tree.
*
* Sends an error response if navigation is impossible (i.e.
@@ -124,7 +128,7 @@ TALER_MINT_parse_post_cleanup_callback (void *con_cls);
* GNUNET_SYSERR on internal error
*/
int
-request_json_require_nav (struct MHD_Connection *connection,
+GNUNET_MINT_parse_navigate_json (struct MHD_Connection *connection,
const json_t *root, ...);
diff --git a/src/mint/taler-mint-httpd_refresh.c b/src/mint/taler-mint-httpd_refresh.c
index 1f19aedb2..ab21e814c 100644
--- a/src/mint/taler-mint-httpd_refresh.c
+++ b/src/mint/taler-mint-httpd_refresh.c
@@ -125,7 +125,7 @@ refresh_accept_denoms (struct MHD_Connection *connection,
int res;
json_t *new_denoms;
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "new_denoms",
JNAV_RET_TYPED_JSON,
JSON_ARRAY,
@@ -142,7 +142,7 @@ refresh_accept_denoms (struct MHD_Connection *connection,
struct TALER_MINT_DenomKeyIssue *dki;
struct TALER_Amount cost;
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "new_denoms",
JNAV_INDEX, (int) i,
JNAV_RET_DATA,
@@ -210,7 +210,7 @@ check_confirm_signature (struct MHD_Connection *connection,
body.purpose.purpose = htonl (TALER_SIGNATURE_REFRESH_MELT_CONFIRM);
body.session_pub = *session_pub;
- res = request_json_require_nav (connection, coin_info,
+ res = GNUNET_MINT_parse_navigate_json (connection, coin_info,
JNAV_FIELD, "confirm_sig",
JNAV_RET_DATA,
&sig,
@@ -259,7 +259,7 @@ request_json_require_coin_public_info (struct MHD_Connection *connection,
GNUNET_assert (NULL != root);
- ret = request_json_require_nav (connection, root,
+ ret = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "coin_pub",
JNAV_RET_DATA,
&r_public_info->coin_pub,
@@ -267,7 +267,7 @@ request_json_require_coin_public_info (struct MHD_Connection *connection,
if (GNUNET_OK != ret)
return ret;
- ret = request_json_require_nav (connection, root,
+ ret = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "denom_sig",
JNAV_RET_DATA,
&r_public_info->denom_sig,
@@ -275,7 +275,7 @@ request_json_require_coin_public_info (struct MHD_Connection *connection,
if (GNUNET_OK != ret)
return ret;
- ret = request_json_require_nav (connection, root,
+ ret = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "denom_pub",
JNAV_RET_DATA,
&r_public_info->denom_pub,
@@ -315,7 +315,7 @@ refresh_accept_melts (struct MHD_Connection *connection,
int res;
json_t *melt_coins;
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "melt_coins",
JNAV_RET_TYPED_JSON,
JSON_ARRAY,
@@ -512,7 +512,7 @@ request_json_check_signature (struct MHD_Connection *connection,
int res;
json_t *el;
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "sig",
JNAV_RET_DATA,
&signature,
@@ -521,7 +521,7 @@ request_json_check_signature (struct MHD_Connection *connection,
if (GNUNET_OK != res)
return res;
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "purpose",
JNAV_RET_TYPED_JSON,
JSON_INTEGER,
@@ -541,7 +541,7 @@ request_json_check_signature (struct MHD_Connection *connection,
"error", "signature invalid (purpose)");
}
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "size",
JNAV_RET_TYPED_JSON,
JSON_INTEGER,
@@ -623,7 +623,7 @@ TALER_MINT_handler_refresh_melt (struct RequestHandler *rh,
}
/* session_pub field must always be present */
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "session_pub",
JNAV_RET_DATA,
&refresh_session_pub,
@@ -833,7 +833,7 @@ TALER_MINT_handler_refresh_commit (struct RequestHandler *rh,
if ( (GNUNET_NO == res) || (NULL == root) )
return MHD_YES;
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "session_pub",
JNAV_RET_DATA,
&refresh_session_pub,
@@ -906,7 +906,7 @@ TALER_MINT_handler_refresh_commit (struct RequestHandler *rh,
{
struct RefreshCommitCoin commit_coin;
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "coin_evs",
JNAV_INDEX, (int) i,
JNAV_INDEX, (int) j,
@@ -927,7 +927,7 @@ TALER_MINT_handler_refresh_commit (struct RequestHandler *rh,
&commit_coin.coin_ev,
sizeof (struct TALER_RSA_BlindedSignaturePurpose));
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "link_encs",
JNAV_INDEX, (int) i,
JNAV_INDEX, (int) j,
@@ -971,7 +971,7 @@ TALER_MINT_handler_refresh_commit (struct RequestHandler *rh,
{
struct RefreshCommitLink commit_link;
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "transfer_pubs",
JNAV_INDEX, (int) i,
JNAV_INDEX, (int) j,
@@ -991,7 +991,7 @@ TALER_MINT_handler_refresh_commit (struct RequestHandler *rh,
&commit_link.transfer_pub,
sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "secret_encs",
JNAV_INDEX, (int) i,
JNAV_INDEX, (int) j,
@@ -1165,7 +1165,7 @@ TALER_MINT_handler_refresh_reveal (struct RequestHandler *rh,
if ( (GNUNET_NO == res) || (NULL == root) )
return MHD_YES;
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "session_pub",
JNAV_RET_DATA,
&refresh_session_pub,
@@ -1216,7 +1216,7 @@ TALER_MINT_handler_refresh_reveal (struct RequestHandler *rh,
struct GNUNET_HashCode transfer_secret;
struct GNUNET_HashCode shared_secret;
- res = request_json_require_nav (connection, root,
+ res = GNUNET_MINT_parse_navigate_json (connection, root,
JNAV_FIELD, "transfer_privs",
JNAV_INDEX, (int) i,
JNAV_INDEX, (int) j,