summaryrefslogtreecommitdiffstats
path: root/src/jansson.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/jansson.c')
-rw-r--r--src/jansson.c83
1 files changed, 57 insertions, 26 deletions
diff --git a/src/jansson.c b/src/jansson.c
index 539f9ab..54a56b9 100644
--- a/src/jansson.c
+++ b/src/jansson.c
@@ -24,17 +24,21 @@
#ifdef JSON_PARSING
static int nft_jansson_load_int_node(json_t *root, const char *node_name,
- json_int_t *val)
+ json_int_t *val, struct nft_parse_err *err)
{
json_t *node;
node = json_object_get(root, node_name);
if (node == NULL) {
+ err->error = NFT_PARSE_EMISSINGNODE;
+ err->node_name = node_name;
errno = EINVAL;
return -1;
}
if (!json_is_integer(node)) {
+ err->error = NFT_PARSE_EBADTYPE;
+ err->node_name = node_name;
errno = ERANGE;
return -1;
}
@@ -43,27 +47,35 @@ static int nft_jansson_load_int_node(json_t *root, const char *node_name,
return 0;
}
-const char *nft_jansson_parse_str(json_t *root, const char *node_name)
+const char *nft_jansson_parse_str(json_t *root, const char *node_name,
+ struct nft_parse_err *err)
{
json_t *node;
const char *val;
node = json_object_get(root, node_name);
if (node == NULL) {
+ err->error = NFT_PARSE_EMISSINGNODE;
+ err->node_name = node_name;
errno = EINVAL;
return NULL;
}
+
val = json_string_value(node);
+ if (val == NULL) {
+ err->error = NFT_PARSE_EBADTYPE;
+ err->node_name = node_name;
+ }
return val;
}
int nft_jansson_parse_val(json_t *root, const char *node_name, int type,
- void *out)
+ void *out, struct nft_parse_err *err)
{
json_int_t val;
- if (nft_jansson_load_int_node(root, node_name, &val) == -1)
+ if (nft_jansson_load_int_node(root, node_name, &val, err) == -1)
return -1;
if (nft_get_value(type, &val, out) == -1)
@@ -77,12 +89,17 @@ bool nft_jansson_node_exist(json_t *root, const char *node_name)
return json_object_get(root, node_name) != NULL;
}
-json_t *nft_jansson_create_root(const char *json, json_error_t *err)
+json_t *nft_jansson_create_root(const char *json, json_error_t *error,
+ struct nft_parse_err *err)
{
json_t *root;
- root = json_loadb(json, strlen(json), 0, err);
+ root = json_loadb(json, strlen(json), 0, error);
if (root == NULL) {
+ err->error = NFT_PARSE_EBADINPUT;
+ err->line = error->line;
+ err->column = error->column;
+ err->node_name = error->source;
errno = EINVAL;
return NULL;
}
@@ -90,12 +107,15 @@ json_t *nft_jansson_create_root(const char *json, json_error_t *err)
return root;
}
-json_t *nft_jansson_get_node(json_t *root, const char *node_name)
+json_t *nft_jansson_get_node(json_t *root, const char *node_name,
+ struct nft_parse_err *err)
{
json_t *node;
node = json_object_get(root, node_name);
if (node == NULL) {
+ err->error = NFT_PARSE_EMISSINGNODE;
+ err->node_name = node_name;
errno = EINVAL;
return NULL;
}
@@ -108,17 +128,18 @@ void nft_jansson_free_root(json_t *root)
json_decref(root);
}
-int nft_jansson_parse_family(json_t *root, void *out)
+int nft_jansson_parse_family(json_t *root, void *out, struct nft_parse_err *err)
{
const char *str;
int family;
- str = nft_jansson_parse_str(root, "family");
+ str = nft_jansson_parse_str(root, "family", err);
if (str == NULL)
return -1;
family = nft_str2family(str);
if (family < 0) {
+ err->node_name = "family";
errno = EINVAL;
return -1;
}
@@ -128,9 +149,9 @@ int nft_jansson_parse_family(json_t *root, void *out)
}
int nft_jansson_parse_reg(json_t *root, const char *node_name, int type,
- void *out)
+ void *out, struct nft_parse_err *err)
{
- if (nft_jansson_parse_val(root, node_name, type, out) < 0)
+ if (nft_jansson_parse_val(root, node_name, type, out, err) < 0)
return -1;
if (*((uint32_t *)out) > NFT_REG_MAX){
@@ -142,38 +163,42 @@ int nft_jansson_parse_reg(json_t *root, const char *node_name, int type,
}
int nft_jansson_str2num(json_t *root, const char *node_name, int base,
- void *out, enum nft_type type)
+ void *out, enum nft_type type, struct nft_parse_err *err)
{
const char *str;
- str = nft_jansson_parse_str(root, node_name);
+ str = nft_jansson_parse_str(root, node_name, err);
if (str == NULL)
return -1;
return nft_strtoi(str, base, out, type);
}
-struct nft_rule_expr *nft_jansson_expr_parse(json_t *root)
+struct nft_rule_expr *nft_jansson_expr_parse(json_t *root,
+ struct nft_parse_err *err)
{
struct nft_rule_expr *e;
const char *type;
int ret;
- type = nft_jansson_parse_str(root, "type");
+ type = nft_jansson_parse_str(root, "type", err);
if (type == NULL)
return NULL;
e = nft_rule_expr_alloc(type);
- if (e == NULL)
- return NULL;;
+ if (e == NULL) {
+ err->node_name = "type";
+ return NULL;
+ }
- ret = e->ops->json_parse(e, root);
+ ret = e->ops->json_parse(e, root, err);
return ret < 0 ? NULL : e;
}
int nft_jansson_data_reg_parse(json_t *root, const char *node_name,
- union nft_data_reg *data_reg)
+ union nft_data_reg *data_reg,
+ struct nft_parse_err *err)
{
json_t *data;
const char *type;
@@ -181,24 +206,27 @@ int nft_jansson_data_reg_parse(json_t *root, const char *node_name,
data = json_object_get(root, node_name);
if (data == NULL) {
+ err->error = NFT_PARSE_EMISSINGNODE;
+ err->node_name = node_name;
errno = EINVAL;
return -1;
}
data = json_object_get(data, "data_reg");
if (data == NULL) {
+ err->error = NFT_PARSE_EMISSINGNODE;
+ err->node_name = "data_reg";
errno = EINVAL;
return -1;
}
- ret = nft_data_reg_json_parse(data_reg, data);
-
+ ret = nft_data_reg_json_parse(data_reg, data, err);
if (ret < 0) {
errno = EINVAL;
return -1;
}
- type = nft_jansson_parse_str(data, "type");
+ type = nft_jansson_parse_str(data, "type", err);
if (type == NULL)
return -1;
@@ -209,29 +237,32 @@ int nft_jansson_data_reg_parse(json_t *root, const char *node_name,
else if (strcmp(type, "chain") == 0)
return DATA_CHAIN;
else {
+ err->error = NFT_PARSE_EBADTYPE;
+ err->node_name = "type";
errno = EINVAL;
return -1;
}
}
-int nft_set_elem_json_parse(struct nft_set_elem *e, json_t *root)
+int nft_set_elem_json_parse(struct nft_set_elem *e, json_t *root,
+ struct nft_parse_err *err)
{
uint32_t uval32;
int set_elem_data;
- if (nft_jansson_parse_val(root, "flags", NFT_TYPE_U32, &uval32) < 0)
+ if (nft_jansson_parse_val(root, "flags", NFT_TYPE_U32, &uval32, err) < 0)
return -1;
nft_set_elem_attr_set_u32(e, NFT_SET_ELEM_ATTR_FLAGS, uval32);
- if (nft_jansson_data_reg_parse(root, "key", &e->key) != DATA_VALUE)
+ if (nft_jansson_data_reg_parse(root, "key", &e->key, err) != DATA_VALUE)
return -1;
e->flags |= (1 << NFT_SET_ELEM_ATTR_KEY);
if (nft_jansson_node_exist(root, "data")) {
set_elem_data = nft_jansson_data_reg_parse(root, "data",
- &e->data);
+ &e->data, err);
switch (set_elem_data) {
case DATA_VALUE:
e->flags |= (1 << NFT_SET_ELEM_ATTR_DATA);