summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2025-03-31 16:47:11 +0200
committerFlorian Westphal <fw@strlen.de>2025-06-05 15:37:43 +0200
commit18c24d89b9977ddc0900be64fe9e95e7ac1ce896 (patch)
treefb81f1bf04475e2484bbf53e4515430c90d2749e
parent69b90023c7220fe283ee38686c758e3494e853d9 (diff)
json: work around fuzzer-induced assert crashes
fuzzer can cause assert failures due to json_pack() returning a NULL value and therefore triggering the assert(out) in __json_pack macro. All instances I saw are due to invalid UTF-8 strings, i.e., table/chain names with non-text characters in them. Work around this for now, replace the assert with a plaintext error message and return NULL instead of abort(). Signed-off-by: Florian Westphal <fw@strlen.de>
-rw-r--r--src/json.c271
-rw-r--r--tests/shell/testcases/bogons/nft-j-f/Assertion__out_failed_assert6
2 files changed, 146 insertions, 131 deletions
diff --git a/src/json.c b/src/json.c
index e64bbf57..a46aed27 100644
--- a/src/json.c
+++ b/src/json.c
@@ -33,14 +33,23 @@
#include <jansson.h>
#include <syslog.h>
-#ifdef DEBUG
-#define __json_pack json_pack
-#define json_pack(...) ({ \
- json_t *__out = __json_pack(__VA_ARGS__); \
- assert(__out); \
- __out; \
-})
-#endif
+static json_t *__nft_json_pack(unsigned int line, const char *fmt, ...)
+{
+ json_error_t error;
+ json_t *value;
+ va_list ap;
+
+ va_start(ap, fmt);
+ value = json_vpack_ex(&error, 0, fmt, ap);
+ va_end(ap);
+
+ if (value)
+ return value;
+
+ fprintf(stderr, "%s:%d: json_pack failure (%s)\n", __FILE__, line, error.text);
+ return NULL;
+}
+#define nft_json_pack(...) __nft_json_pack(__LINE__, __VA_ARGS__)
static int json_array_extend_new(json_t *array, json_t *other_array)
{
@@ -84,7 +93,7 @@ static json_t *expr_print_json(const struct expr *expr, struct output_ctx *octx)
fclose(octx->output_fp);
octx->output_fp = fp;
- return json_pack("s", buf);
+ return nft_json_pack("s", buf);
}
static json_t *set_dtype_json(const struct expr *key)
@@ -99,7 +108,7 @@ static json_t *set_dtype_json(const struct expr *key)
if (!root)
root = jtok;
else if (json_is_string(root))
- root = json_pack("[o, o]", root, jtok);
+ root = nft_json_pack("[o, o]", root, jtok);
else
json_array_append_new(root, jtok);
tok = strtok_r(NULL, " .", &tok_safe);
@@ -116,7 +125,7 @@ static json_t *set_key_dtype_json(const struct set *set,
if (!use_typeof)
return set_dtype_json(set->key);
- return json_pack("{s:o}", "typeof", expr_print_json(set->key, octx));
+ return nft_json_pack("{s:o}", "typeof", expr_print_json(set->key, octx));
}
static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx)
@@ -139,7 +148,7 @@ static json_t *stmt_print_json(const struct stmt *stmt, struct output_ctx *octx)
fclose(octx->output_fp);
octx->output_fp = fp;
- return json_pack("s", buf);
+ return nft_json_pack("s", buf);
}
static json_t *set_stmt_list_json(const struct list_head *stmt_list,
@@ -178,7 +187,7 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
type = "set";
}
- root = json_pack("{s:s, s:s, s:s, s:o, s:I}",
+ root = nft_json_pack("{s:s, s:s, s:s, s:o, s:I}",
"family", family2str(set->handle.family),
"name", set->handle.set.name,
"table", set->handle.table.name,
@@ -192,24 +201,24 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
if (!(set->flags & (NFT_SET_CONSTANT))) {
if (set->policy != NFT_SET_POL_PERFORMANCE) {
- tmp = json_pack("s", set_policy2str(set->policy));
+ tmp = nft_json_pack("s", set_policy2str(set->policy));
json_object_set_new(root, "policy", tmp);
}
if (set->desc.size) {
- tmp = json_pack("i", set->desc.size);
+ tmp = nft_json_pack("i", set->desc.size);
json_object_set_new(root, "size", tmp);
}
}
tmp = json_array();
if (set->flags & NFT_SET_CONSTANT)
- json_array_append_new(tmp, json_pack("s", "constant"));
+ json_array_append_new(tmp, nft_json_pack("s", "constant"));
if (set->flags & NFT_SET_INTERVAL)
- json_array_append_new(tmp, json_pack("s", "interval"));
+ json_array_append_new(tmp, nft_json_pack("s", "interval"));
if (set->flags & NFT_SET_TIMEOUT)
- json_array_append_new(tmp, json_pack("s", "timeout"));
+ json_array_append_new(tmp, nft_json_pack("s", "timeout"));
if (set->flags & NFT_SET_EVAL)
- json_array_append_new(tmp, json_pack("s", "dynamic"));
+ json_array_append_new(tmp, nft_json_pack("s", "dynamic"));
json_add_array_new(root, "flags", tmp);
if (set->timeout) {
@@ -217,7 +226,7 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
json_object_set_new(root, "timeout", tmp);
}
if (set->gc_int) {
- tmp = json_pack("i", set->gc_int / 1000);
+ tmp = nft_json_pack("i", set->gc_int / 1000);
json_object_set_new(root, "gc-interval", tmp);
}
if (set->automerge)
@@ -238,7 +247,7 @@ static json_t *set_print_json(struct output_ctx *octx, const struct set *set)
set_stmt_list_json(&set->stmt_list, octx));
}
- return json_pack("{s:o}", type, root);
+ return nft_json_pack("{s:o}", type, root);
}
/* XXX: Merge with set_print_json()? */
@@ -247,7 +256,7 @@ static json_t *element_print_json(struct output_ctx *octx,
{
json_t *root = expr_print_json(set->init, octx);
- return json_pack("{s: {s:s, s:s, s:s, s:o}}", "element",
+ return nft_json_pack("{s: {s:s, s:s, s:s, s:o}}", "element",
"family", family2str(set->handle.family),
"table", set->handle.table.name,
"name", set->handle.set.name,
@@ -260,7 +269,7 @@ static json_t *rule_print_json(struct output_ctx *octx,
const struct stmt *stmt;
json_t *root, *tmp;
- root = json_pack("{s:s, s:s, s:s, s:I}",
+ root = nft_json_pack("{s:s, s:s, s:s, s:I}",
"family", family2str(rule->handle.family),
"table", rule->handle.table.name,
"chain", rule->handle.chain.name,
@@ -280,7 +289,7 @@ static json_t *rule_print_json(struct output_ctx *octx,
json_decref(tmp);
}
- return json_pack("{s:o}", "rule", root);
+ return nft_json_pack("{s:o}", "rule", root);
}
static json_t *chain_print_json(const struct chain *chain)
@@ -288,7 +297,7 @@ static json_t *chain_print_json(const struct chain *chain)
json_t *root, *tmp, *devs = NULL;
int priority, policy, i;
- root = json_pack("{s:s, s:s, s:s, s:I}",
+ root = nft_json_pack("{s:s, s:s, s:s, s:I}",
"family", family2str(chain->handle.family),
"table", chain->handle.table.name,
"name", chain->handle.chain.name,
@@ -308,7 +317,7 @@ static json_t *chain_print_json(const struct chain *chain)
policy = NF_ACCEPT;
}
- tmp = json_pack("{s:s, s:s, s:i, s:s}",
+ tmp = nft_json_pack("{s:s, s:s, s:i, s:s}",
"type", chain->type.str,
"hook", hooknum2str(chain->handle.family,
chain->hook.num),
@@ -320,7 +329,7 @@ static json_t *chain_print_json(const struct chain *chain)
if (!devs)
devs = json_string(dev);
else if (json_is_string(devs))
- devs = json_pack("[o, s]", devs, dev);
+ devs = nft_json_pack("[o, s]", devs, dev);
else
json_array_append_new(devs, json_string(dev));
}
@@ -331,7 +340,7 @@ static json_t *chain_print_json(const struct chain *chain)
json_decref(tmp);
}
- return json_pack("{s:o}", "chain", root);
+ return nft_json_pack("{s:o}", "chain", root);
}
static json_t *proto_name_json(uint8_t proto)
@@ -367,28 +376,28 @@ static json_t *obj_print_json(const struct obj *obj)
json_t *root, *tmp, *flags;
uint64_t rate, burst;
- root = json_pack("{s:s, s:s, s:s, s:I}",
+ root = nft_json_pack("{s:s, s:s, s:s, s:I}",
"family", family2str(obj->handle.family),
"name", obj->handle.obj.name,
"table", obj->handle.table.name,
"handle", obj->handle.handle.id);
if (obj->comment) {
- tmp = json_pack("{s:s}", "comment", obj->comment);
+ tmp = nft_json_pack("{s:s}", "comment", obj->comment);
json_object_update(root, tmp);
json_decref(tmp);
}
switch (obj->type) {
case NFT_OBJECT_COUNTER:
- tmp = json_pack("{s:I, s:I}",
+ tmp = nft_json_pack("{s:I, s:I}",
"packets", obj->counter.packets,
"bytes", obj->counter.bytes);
json_object_update(root, tmp);
json_decref(tmp);
break;
case NFT_OBJECT_QUOTA:
- tmp = json_pack("{s:I, s:I, s:b}",
+ tmp = nft_json_pack("{s:I, s:I, s:b}",
"bytes", obj->quota.bytes,
"used", obj->quota.used,
"inv", obj->quota.flags & NFT_QUOTA_F_INV);
@@ -396,13 +405,13 @@ static json_t *obj_print_json(const struct obj *obj)
json_decref(tmp);
break;
case NFT_OBJECT_SECMARK:
- tmp = json_pack("{s:s}",
+ tmp = nft_json_pack("{s:s}",
"context", obj->secmark.ctx);
json_object_update(root, tmp);
json_decref(tmp);
break;
case NFT_OBJECT_CT_HELPER:
- tmp = json_pack("{s:s, s:o, s:s}",
+ tmp = nft_json_pack("{s:s, s:o, s:s}",
"type", obj->ct_helper.name, "protocol",
proto_name_json(obj->ct_helper.l4proto),
"l3proto", family2str(obj->ct_helper.l3proto));
@@ -412,7 +421,7 @@ static json_t *obj_print_json(const struct obj *obj)
case NFT_OBJECT_CT_TIMEOUT:
tmp = timeout_policy_json(obj->ct_timeout.l4proto,
obj->ct_timeout.timeout);
- tmp = json_pack("{s:o, s:s, s:o}",
+ tmp = nft_json_pack("{s:o, s:s, s:o}",
"protocol",
proto_name_json(obj->ct_timeout.l4proto),
"l3proto", family2str(obj->ct_timeout.l3proto),
@@ -421,7 +430,7 @@ static json_t *obj_print_json(const struct obj *obj)
json_decref(tmp);
break;
case NFT_OBJECT_CT_EXPECT:
- tmp = json_pack("{s:o, s:I, s:I, s:I, s:s}",
+ tmp = nft_json_pack("{s:o, s:I, s:I, s:I, s:s}",
"protocol",
proto_name_json(obj->ct_expect.l4proto),
"dport", obj->ct_expect.dport,
@@ -440,7 +449,7 @@ static json_t *obj_print_json(const struct obj *obj)
burst_unit = get_rate(obj->limit.burst, &burst);
}
- tmp = json_pack("{s:I, s:s}",
+ tmp = nft_json_pack("{s:I, s:s}",
"rate", rate,
"per", get_unit(obj->limit.unit));
@@ -460,9 +469,9 @@ static json_t *obj_print_json(const struct obj *obj)
json_decref(tmp);
break;
case NFT_OBJECT_SYNPROXY:
- tmp = json_pack("{s:i, s:i}",
- "mss", obj->synproxy.mss,
- "wscale", obj->synproxy.wscale);
+ tmp = nft_json_pack("{s:i, s:i}",
+ "mss", obj->synproxy.mss,
+ "wscale", obj->synproxy.wscale);
flags = json_array();
if (obj->synproxy.flags & NF_SYNPROXY_OPT_TIMESTAMP)
@@ -476,7 +485,7 @@ static json_t *obj_print_json(const struct obj *obj)
break;
}
- return json_pack("{s:o}", type, root);
+ return nft_json_pack("{s:o}", type, root);
}
static json_t *flowtable_print_json(const struct flowtable *ftable)
@@ -489,7 +498,7 @@ static json_t *flowtable_print_json(const struct flowtable *ftable)
BYTEORDER_HOST_ENDIAN, sizeof(int));
}
- root = json_pack("{s:s, s:s, s:s, s:I, s:s, s:i}",
+ root = nft_json_pack("{s:s, s:s, s:s, s:I, s:s, s:i}",
"family", family2str(ftable->handle.family),
"name", ftable->handle.flowtable.name,
"table", ftable->handle.table.name,
@@ -502,14 +511,14 @@ static json_t *flowtable_print_json(const struct flowtable *ftable)
if (!devs)
devs = json_string(dev);
else if (json_is_string(devs))
- devs = json_pack("[o, s]", devs, dev);
+ devs = nft_json_pack("[o, s]", devs, dev);
else
json_array_append_new(devs, json_string(dev));
}
if (devs)
json_object_set_new(root, "dev", devs);
- return json_pack("{s:o}", "flowtable", root);
+ return nft_json_pack("{s:o}", "flowtable", root);
}
static json_t *table_flags_json(const struct table *table)
@@ -533,7 +542,7 @@ static json_t *table_print_json(const struct table *table)
{
json_t *root;
- root = json_pack("{s:s, s:s, s:I}",
+ root = nft_json_pack("{s:s, s:s, s:I}",
"family", family2str(table->handle.family),
"name", table->handle.table.name,
"handle", table->handle.handle.id);
@@ -542,7 +551,7 @@ static json_t *table_print_json(const struct table *table)
if (table->comment)
json_object_set_new(root, "comment", json_string(table->comment));
- return json_pack("{s:o}", "table", root);
+ return nft_json_pack("{s:o}", "table", root);
}
static json_t *
@@ -563,13 +572,13 @@ __binop_expr_json(int op, const struct expr *expr, struct output_ctx *octx)
json_t *binop_expr_json(const struct expr *expr, struct output_ctx *octx)
{
- return json_pack("{s:o}", expr_op_symbols[expr->op],
+ return nft_json_pack("{s:o}", expr_op_symbols[expr->op],
__binop_expr_json(expr->op, expr, octx));
}
json_t *relational_expr_json(const struct expr *expr, struct output_ctx *octx)
{
- return json_pack("{s:{s:s, s:o, s:o}}", "match",
+ return nft_json_pack("{s:{s:s, s:o, s:o}}", "match",
"op", expr_op_symbols[expr->op] ? : "in",
"left", expr_print_json(expr->left, octx),
"right", expr_print_json(expr->right, octx));
@@ -582,7 +591,7 @@ json_t *range_expr_json(const struct expr *expr, struct output_ctx *octx)
octx->flags &= ~NFT_CTX_OUTPUT_SERVICE;
octx->flags |= NFT_CTX_OUTPUT_NUMERIC_PROTO;
- root = json_pack("{s:[o, o]}", "range",
+ root = nft_json_pack("{s:[o, o]}", "range",
expr_print_json(expr->left, octx),
expr_print_json(expr->right, octx));
octx->flags = flags;
@@ -592,7 +601,7 @@ json_t *range_expr_json(const struct expr *expr, struct output_ctx *octx)
json_t *meta_expr_json(const struct expr *expr, struct output_ctx *octx)
{
- return json_pack("{s:{s:s}}", "meta",
+ return nft_json_pack("{s:{s:s}}", "meta",
"key", meta_templates[expr->meta.key].token);
}
@@ -602,23 +611,23 @@ json_t *payload_expr_json(const struct expr *expr, struct output_ctx *octx)
if (payload_is_known(expr)) {
if (expr->payload.inner_desc) {
- root = json_pack("{s:s, s:s, s:s}",
+ root = nft_json_pack("{s:s, s:s, s:s}",
"tunnel", expr->payload.inner_desc->name,
"protocol", expr->payload.desc->name,
"field", expr->payload.tmpl->token);
} else {
- root = json_pack("{s:s, s:s}",
+ root = nft_json_pack("{s:s, s:s}",
"protocol", expr->payload.desc->name,
"field", expr->payload.tmpl->token);
}
} else {
- root = json_pack("{s:s, s:i, s:i}",
+ root = nft_json_pack("{s:s, s:i, s:i}",
"base", proto_base_tokens[expr->payload.base],
"offset", expr->payload.offset,
"len", expr->len);
}
- return json_pack("{s:o}", "payload", root);
+ return nft_json_pack("{s:o}", "payload", root);
}
json_t *ct_expr_json(const struct expr *expr, struct output_ctx *octx)
@@ -627,7 +636,7 @@ json_t *ct_expr_json(const struct expr *expr, struct output_ctx *octx)
enum nft_ct_keys key = expr->ct.key;
json_t *root;
- root = json_pack("{s:s}", "key", ct_templates[key].token);
+ root = nft_json_pack("{s:s}", "key", ct_templates[key].token);
if (expr->ct.direction < 0)
goto out;
@@ -635,7 +644,7 @@ json_t *ct_expr_json(const struct expr *expr, struct output_ctx *octx)
if (dirstr)
json_object_set_new(root, "dir", json_string(dirstr));
out:
- return json_pack("{s:o}", "ct", root);
+ return nft_json_pack("{s:o}", "ct", root);
}
json_t *concat_expr_json(const struct expr *expr, struct output_ctx *octx)
@@ -646,7 +655,7 @@ json_t *concat_expr_json(const struct expr *expr, struct output_ctx *octx)
list_for_each_entry(i, &expr->expressions, list)
json_array_append_new(array, expr_print_json(i, octx));
- return json_pack("{s:o}", "concat", array);
+ return nft_json_pack("{s:o}", "concat", array);
}
json_t *set_expr_json(const struct expr *expr, struct output_ctx *octx)
@@ -657,7 +666,7 @@ json_t *set_expr_json(const struct expr *expr, struct output_ctx *octx)
list_for_each_entry(i, &expr->expressions, list)
json_array_append_new(array, expr_print_json(i, octx));
- return json_pack("{s:o}", "set", array);
+ return nft_json_pack("{s:o}", "set", array);
}
json_t *set_ref_expr_json(const struct expr *expr, struct output_ctx *octx)
@@ -665,7 +674,7 @@ json_t *set_ref_expr_json(const struct expr *expr, struct output_ctx *octx)
if (set_is_anonymous(expr->set->flags)) {
return expr_print_json(expr->set->init, octx);
} else {
- return json_pack("s+", "@", expr->set->handle.set.name);
+ return nft_json_pack("s+", "@", expr->set->handle.set.name);
}
}
@@ -681,7 +690,7 @@ json_t *set_elem_expr_json(const struct expr *expr, struct output_ctx *octx)
/* these element attributes require formal set elem syntax */
if (expr->timeout || expr->expiration || expr->comment ||
!list_empty(&expr->stmt_list)) {
- root = json_pack("{s:o}", "val", root);
+ root = nft_json_pack("{s:o}", "val", root);
if (expr->timeout) {
tmp = json_integer(expr->timeout / 1000);
@@ -703,7 +712,7 @@ json_t *set_elem_expr_json(const struct expr *expr, struct output_ctx *octx)
/* TODO: only one statement per element. */
break;
}
- return json_pack("{s:o}", "elem", root);
+ return nft_json_pack("{s:o}", "elem", root);
}
return root;
@@ -713,7 +722,7 @@ json_t *prefix_expr_json(const struct expr *expr, struct output_ctx *octx)
{
json_t *root = expr_print_json(expr->prefix, octx);
- return json_pack("{s:{s:o, s:i}}", "prefix",
+ return nft_json_pack("{s:{s:o, s:i}}", "prefix",
"addr", root,
"len", expr->prefix_len);
}
@@ -726,7 +735,7 @@ json_t *list_expr_json(const struct expr *expr, struct output_ctx *octx)
list_for_each_entry(i, &expr->expressions, list)
json_array_append_new(array, expr_print_json(i, octx));
- //return json_pack("{s:s, s:o}", "type", "list", "val", array);
+ //return nft_json_pack("{s:s, s:o}", "type", "list", "val", array);
return array;
}
@@ -737,7 +746,7 @@ json_t *unary_expr_json(const struct expr *expr, struct output_ctx *octx)
json_t *mapping_expr_json(const struct expr *expr, struct output_ctx *octx)
{
- return json_pack("[o, o]",
+ return nft_json_pack("[o, o]",
expr_print_json(expr->left, octx),
expr_print_json(expr->right, octx));
}
@@ -750,7 +759,7 @@ json_t *map_expr_json(const struct expr *expr, struct output_ctx *octx)
expr->mappings->set->data->dtype->type == TYPE_VERDICT)
type = "vmap";
- return json_pack("{s:{s:o, s:o}}", type,
+ return nft_json_pack("{s:{s:o, s:o}}", type,
"key", expr_print_json(expr->map, octx),
"data", expr_print_json(expr->mappings, octx));
}
@@ -772,36 +781,36 @@ json_t *exthdr_expr_json(const struct expr *expr, struct output_ctx *octx)
if (offset < 4)
offstr = offstrs[offset];
- root = json_pack("{s:s+}", "name", desc, offstr);
+ root = nft_json_pack("{s:s+}", "name", desc, offstr);
if (!is_exists)
json_object_set_new(root, "field", json_string(field));
} else {
- root = json_pack("{s:i, s:i, s:i}",
+ root = nft_json_pack("{s:i, s:i, s:i}",
"base", expr->exthdr.raw_type,
"offset", expr->exthdr.offset,
"len", expr->len);
}
- return json_pack("{s:o}", "tcp option", root);
+ return nft_json_pack("{s:o}", "tcp option", root);
}
if (expr->exthdr.op == NFT_EXTHDR_OP_DCCP) {
- root = json_pack("{s:i}", "type", expr->exthdr.raw_type);
- return json_pack("{s:o}", "dccp option", root);
+ root = nft_json_pack("{s:i}", "type", expr->exthdr.raw_type);
+ return nft_json_pack("{s:o}", "dccp option", root);
}
- root = json_pack("{s:s}", "name", desc);
+ root = nft_json_pack("{s:s}", "name", desc);
if (!is_exists)
json_object_set_new(root, "field", json_string(field));
switch (expr->exthdr.op) {
case NFT_EXTHDR_OP_IPV4:
- return json_pack("{s:o}", "ip option", root);
+ return nft_json_pack("{s:o}", "ip option", root);
case NFT_EXTHDR_OP_SCTP:
- return json_pack("{s:o}", "sctp chunk", root);
+ return nft_json_pack("{s:o}", "sctp chunk", root);
default:
- return json_pack("{s:o}", "exthdr", root);
+ return nft_json_pack("{s:o}", "exthdr", root);
}
}
@@ -838,15 +847,15 @@ json_t *verdict_expr_json(const struct expr *expr, struct output_ctx *octx)
return NULL;
}
if (chain)
- return json_pack("{s:{s:o}}", name, "target", chain);
+ return nft_json_pack("{s:{s:o}}", name, "target", chain);
else
- return json_pack("{s:n}", name);
+ return nft_json_pack("{s:n}", name);
}
json_t *rt_expr_json(const struct expr *expr, struct output_ctx *octx)
{
const char *key = rt_templates[expr->rt.key].token;
- json_t *root = json_pack("{s:s}", "key", key);
+ json_t *root = nft_json_pack("{s:s}", "key", key);
const char *family = NULL;
switch (expr->rt.key) {
@@ -863,7 +872,7 @@ json_t *rt_expr_json(const struct expr *expr, struct output_ctx *octx)
if (family)
json_object_set_new(root, "family", json_string(family));
- return json_pack("{s:o}", "rt", root);
+ return nft_json_pack("{s:o}", "rt", root);
}
json_t *numgen_expr_json(const struct expr *expr, struct output_ctx *octx)
@@ -882,7 +891,7 @@ json_t *numgen_expr_json(const struct expr *expr, struct output_ctx *octx)
break;
}
- return json_pack("{s:{s:s, s:i, s:i}}", "numgen",
+ return nft_json_pack("{s:{s:s, s:i, s:i}}", "numgen",
"mode", mode,
"mod", expr->numgen.mod,
"offset", expr->numgen.offset);
@@ -904,7 +913,7 @@ json_t *hash_expr_json(const struct expr *expr, struct output_ctx *octx)
break;
}
- root = json_pack("{s:i}", "mod", expr->hash.mod);
+ root = nft_json_pack("{s:i}", "mod", expr->hash.mod);
if (expr->hash.seed_set)
json_object_set_new(root, "seed",
json_integer(expr->hash.seed));
@@ -914,7 +923,7 @@ json_t *hash_expr_json(const struct expr *expr, struct output_ctx *octx)
if (jexpr)
json_object_set_new(root, "expr", jexpr);
- return json_pack("{s:o}", type, root);
+ return nft_json_pack("{s:o}", type, root);
}
json_t *fib_expr_json(const struct expr *expr, struct output_ctx *octx)
@@ -923,7 +932,7 @@ json_t *fib_expr_json(const struct expr *expr, struct output_ctx *octx)
unsigned int flags = expr->fib.flags & ~NFTA_FIB_F_PRESENT;
json_t *root;
- root = json_pack("{s:s}", "result", fib_result_str(expr->fib.result));
+ root = nft_json_pack("{s:s}", "result", fib_result_str(expr->fib.result));
if (flags) {
json_t *tmp = json_array();
@@ -940,7 +949,7 @@ json_t *fib_expr_json(const struct expr *expr, struct output_ctx *octx)
json_add_array_new(root, "flags", tmp);
}
- return json_pack("{s:o}", "fib", root);
+ return nft_json_pack("{s:o}", "fib", root);
}
static json_t *symbolic_constant_json(const struct symbol_table *tbl,
@@ -1013,7 +1022,7 @@ json_t *constant_expr_json(const struct expr *expr, struct output_ctx *octx)
json_t *socket_expr_json(const struct expr *expr, struct output_ctx *octx)
{
- return json_pack("{s:{s:s}}", "socket", "key",
+ return nft_json_pack("{s:{s:s}}", "socket", "key",
socket_templates[expr->socket.key].token);
}
@@ -1022,9 +1031,9 @@ json_t *osf_expr_json(const struct expr *expr, struct output_ctx *octx)
json_t *root;
if (expr->osf.flags & NFT_OSF_F_VERSION)
- root = json_pack("{s:s}", "key", "version");
+ root = nft_json_pack("{s:s}", "key", "version");
else
- root = json_pack("{s:s}", "key", "name");
+ root = nft_json_pack("{s:s}", "key", "name");
switch (expr->osf.ttl) {
case 1:
@@ -1035,7 +1044,7 @@ json_t *osf_expr_json(const struct expr *expr, struct output_ctx *octx)
break;
}
- return json_pack("{s:o}", "osf", root);
+ return nft_json_pack("{s:o}", "osf", root);
}
json_t *xfrm_expr_json(const struct expr *expr, struct output_ctx *octx)
@@ -1072,7 +1081,7 @@ json_t *xfrm_expr_json(const struct expr *expr, struct output_ctx *octx)
break;
}
- root = json_pack("{s:s}", "key", name);
+ root = nft_json_pack("{s:s}", "key", name);
if (family)
json_object_set_new(root, "family", json_string(family));
@@ -1080,7 +1089,7 @@ json_t *xfrm_expr_json(const struct expr *expr, struct output_ctx *octx)
json_object_set_new(root, "dir", json_string(dirstr));
json_object_set_new(root, "spnum", json_integer(expr->xfrm.spnum));
- return json_pack("{s:o}", "ipsec", root);
+ return nft_json_pack("{s:o}", "ipsec", root);
}
json_t *integer_type_json(const struct expr *expr, struct output_ctx *octx)
@@ -1202,21 +1211,21 @@ json_t *expr_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
json_t *flow_offload_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
{
- return json_pack("{s:{s:s, s:s+}}", "flow",
+ return nft_json_pack("{s:{s:s, s:s+}}", "flow",
"op", "add", "flowtable",
"@", stmt->flow.table_name);
}
json_t *payload_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
{
- return json_pack("{s: {s:o, s:o}}", "mangle",
+ return nft_json_pack("{s: {s:o, s:o}}", "mangle",
"key", expr_print_json(stmt->payload.expr, octx),
"value", expr_print_json(stmt->payload.val, octx));
}
json_t *exthdr_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
{
- return json_pack("{s: {s:o, s:o}}", "mangle",
+ return nft_json_pack("{s: {s:o, s:o}}", "mangle",
"key", expr_print_json(stmt->exthdr.expr, octx),
"value", expr_print_json(stmt->exthdr.val, octx));
}
@@ -1228,7 +1237,7 @@ json_t *quota_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
json_t *root;
data_unit = get_rate(stmt->quota.bytes, &bytes);
- root = json_pack("{s:I, s:s}",
+ root = nft_json_pack("{s:I, s:s}",
"val", bytes,
"val_unit", data_unit);
@@ -1240,7 +1249,7 @@ json_t *quota_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
json_object_set_new(root, "used_unit", json_string(data_unit));
}
- return json_pack("{s:o}", "quota", root);
+ return nft_json_pack("{s:o}", "quota", root);
}
json_t *ct_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
@@ -1253,7 +1262,7 @@ json_t *ct_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
},
};
- return json_pack("{s:{s:o, s:o}}", "mangle",
+ return nft_json_pack("{s:{s:o, s:o}}", "mangle",
"key", ct_expr_json(&expr, octx),
"value", expr_print_json(stmt->ct.expr, octx));
}
@@ -1271,7 +1280,7 @@ json_t *limit_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
burst_unit = get_rate(stmt->limit.burst, &burst);
}
- root = json_pack("{s:I, s:I, s:s}",
+ root = nft_json_pack("{s:I, s:I, s:s}",
"rate", rate,
"burst", burst,
"per", get_unit(stmt->limit.unit));
@@ -1283,14 +1292,14 @@ json_t *limit_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
json_object_set_new(root, "burst_unit",
json_string(burst_unit));
- return json_pack("{s:o}", "limit", root);
+ return nft_json_pack("{s:o}", "limit", root);
}
json_t *fwd_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
{
json_t *root, *tmp;
- root = json_pack("{s:o}", "dev", expr_print_json(stmt->fwd.dev, octx));
+ root = nft_json_pack("{s:o}", "dev", expr_print_json(stmt->fwd.dev, octx));
if (stmt->fwd.addr) {
tmp = json_string(family2str(stmt->fwd.family));
@@ -1300,12 +1309,12 @@ json_t *fwd_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
json_object_set_new(root, "addr", tmp);
}
- return json_pack("{s:o}", "fwd", root);
+ return nft_json_pack("{s:o}", "fwd", root);
}
json_t *notrack_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
{
- return json_pack("{s:n}", "notrack");
+ return nft_json_pack("{s:n}", "notrack");
}
json_t *dup_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
@@ -1313,27 +1322,27 @@ json_t *dup_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
json_t *root;
if (stmt->dup.to) {
- root = json_pack("{s:o}", "addr", expr_print_json(stmt->dup.to, octx));
+ root = nft_json_pack("{s:o}", "addr", expr_print_json(stmt->dup.to, octx));
if (stmt->dup.dev)
json_object_set_new(root, "dev",
expr_print_json(stmt->dup.dev, octx));
} else {
root = json_null();
}
- return json_pack("{s:o}", "dup", root);
+ return nft_json_pack("{s:o}", "dup", root);
}
json_t *meta_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
{
json_t *root;
- root = json_pack("{s:{s:s}}", "meta",
+ root = nft_json_pack("{s:{s:s}}", "meta",
"key", meta_templates[stmt->meta.key].token);
- root = json_pack("{s:o, s:o}",
+ root = nft_json_pack("{s:o, s:o}",
"key", root,
"value", expr_print_json(stmt->meta.expr, octx));
- return json_pack("{s:o}", "mangle", root);
+ return nft_json_pack("{s:o}", "mangle", root);
}
json_t *log_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
@@ -1382,7 +1391,7 @@ json_t *log_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
root = json_null();
}
- return json_pack("{s:o}", "log", root);
+ return nft_json_pack("{s:o}", "log", root);
}
static json_t *nat_flags_json(uint32_t flags)
@@ -1444,7 +1453,7 @@ json_t *nat_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
root = json_null();
}
- return json_pack("{s:o}", nat_etype2str(stmt->nat.type), root);
+ return nft_json_pack("{s:o}", nat_etype2str(stmt->nat.type), root);
}
json_t *reject_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
@@ -1474,7 +1483,7 @@ json_t *reject_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
}
if (!type && !jexpr)
- return json_pack("{s:n}", "reject");
+ return nft_json_pack("{s:n}", "reject");
root = json_object();
if (type)
@@ -1482,15 +1491,15 @@ json_t *reject_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
if (jexpr)
json_object_set_new(root, "expr", jexpr);
- return json_pack("{s:o}", "reject", root);
+ return nft_json_pack("{s:o}", "reject", root);
}
json_t *counter_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
{
if (nft_output_stateless(octx))
- return json_pack("{s:n}", "counter");
+ return nft_json_pack("{s:n}", "counter");
- return json_pack("{s:{s:I, s:I}}", "counter",
+ return nft_json_pack("{s:{s:I, s:I}}", "counter",
"packets", stmt->counter.packets,
"bytes", stmt->counter.bytes);
}
@@ -1498,16 +1507,16 @@ json_t *counter_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
json_t *last_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
{
if (nft_output_stateless(octx) || stmt->last.set == 0)
- return json_pack("{s:n}", "last");
+ return nft_json_pack("{s:n}", "last");
- return json_pack("{s:{s:I}}", "last", "used", stmt->last.used);
+ return nft_json_pack("{s:{s:I}}", "last", "used", stmt->last.used);
}
json_t *set_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
{
json_t *root;
- root = json_pack("{s:s, s:o, s:s+}",
+ root = nft_json_pack("{s:s, s:o, s:s+}",
"op", set_stmt_op_names[stmt->set.op],
"elem", expr_print_json(stmt->set.key, octx),
"set", "@", stmt->set.set->set->handle.set.name);
@@ -1518,14 +1527,14 @@ json_t *set_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
octx));
}
- return json_pack("{s:o}", "set", root);
+ return nft_json_pack("{s:o}", "set", root);
}
json_t *map_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
{
json_t *root;
- root = json_pack("{s:s, s:o, s:o, s:s+}",
+ root = nft_json_pack("{s:s, s:o, s:o, s:s+}",
"op", set_stmt_op_names[stmt->map.op],
"elem", expr_print_json(stmt->map.key, octx),
"data", expr_print_json(stmt->map.data, octx),
@@ -1537,7 +1546,7 @@ json_t *map_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
octx));
}
- return json_pack("{s:o}", "map", root);
+ return nft_json_pack("{s:o}", "map", root);
}
json_t *objref_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
@@ -1549,7 +1558,7 @@ json_t *objref_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
else
name = objref_type_name(stmt->objref.type);
- return json_pack("{s:o}", name, expr_print_json(stmt->objref.expr, octx));
+ return nft_json_pack("{s:o}", name, expr_print_json(stmt->objref.expr, octx));
}
json_t *meter_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
@@ -1561,7 +1570,7 @@ json_t *meter_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
tmp = stmt_print_json(stmt->meter.stmt, octx);
octx->flags = flags;
- root = json_pack("{s:o, s:o, s:i}",
+ root = nft_json_pack("{s:o, s:o, s:i}",
"key", expr_print_json(stmt->meter.key, octx),
"stmt", tmp,
"size", stmt->meter.size);
@@ -1570,7 +1579,7 @@ json_t *meter_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
json_object_set_new(root, "name", tmp);
}
- return json_pack("{s:o}", "meter", root);
+ return nft_json_pack("{s:o}", "meter", root);
}
json_t *queue_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
@@ -1595,7 +1604,7 @@ json_t *queue_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
root = json_null();
}
- return json_pack("{s:o}", "queue", root);
+ return nft_json_pack("{s:o}", "queue", root);
}
json_t *verdict_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
@@ -1605,12 +1614,12 @@ json_t *verdict_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
json_t *connlimit_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
{
- json_t *root = json_pack("{s:i}", "val", stmt->connlimit.count);
+ json_t *root = nft_json_pack("{s:i}", "val", stmt->connlimit.count);
if (stmt->connlimit.flags & NFT_CONNLIMIT_F_INV)
json_object_set_new(root, "inv", json_true());
- return json_pack("{s:o}", "ct count", root);
+ return nft_json_pack("{s:o}", "ct count", root);
}
json_t *tproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
@@ -1633,7 +1642,7 @@ json_t *tproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
json_object_set_new(root, "port", tmp);
}
- return json_pack("{s:o}", "tproxy", root);
+ return nft_json_pack("{s:o}", "tproxy", root);
}
json_t *synproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
@@ -1658,12 +1667,12 @@ json_t *synproxy_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
root = json_null();
}
- return json_pack("{s:o}", "synproxy", root);
+ return nft_json_pack("{s:o}", "synproxy", root);
}
json_t *optstrip_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
{
- return json_pack("{s:o}", "reset",
+ return nft_json_pack("{s:o}", "reset",
expr_print_json(stmt->optstrip.expr, octx));
}
@@ -1675,7 +1684,7 @@ json_t *xt_stmt_json(const struct stmt *stmt, struct output_ctx *octx)
[NFT_XT_WATCHER] = "watcher",
};
- return json_pack("{s:{s:s, s:s}}", "xt",
+ return nft_json_pack("{s:{s:s, s:s}}", "xt",
"type", xt_typename[stmt->xt.type],
"name", stmt->xt.name);
}
@@ -1820,7 +1829,7 @@ static json_t *do_list_set_json(struct netlink_ctx *ctx,
return json_null();
}
- return json_pack("[o]", set_print_json(&ctx->nft->output, set));
+ return nft_json_pack("[o]", set_print_json(&ctx->nft->output, set));
}
static json_t *do_list_sets_json(struct netlink_ctx *ctx, struct cmd *cmd)
@@ -1918,7 +1927,7 @@ static json_t *do_list_flowtables_json(struct netlink_ctx *ctx, struct cmd *cmd)
static json_t *generate_json_metainfo(void)
{
- return json_pack("{s: {s:s, s:s, s:i}}", "metainfo",
+ return nft_json_pack("{s: {s:s, s:s, s:i}}", "metainfo",
"version", PACKAGE_VERSION,
"release_name", RELEASE_NAME,
"json_schema_version", JSON_SCHEMA_VERSION);
@@ -2036,7 +2045,7 @@ int do_command_list_json(struct netlink_ctx *ctx, struct cmd *cmd)
json_array_insert_new(root, 0, generate_json_metainfo());
- root = json_pack("{s:o}", "nftables", root);
+ root = nft_json_pack("{s:o}", "nftables", root);
json_dumpf(root, ctx->nft->output.output_fp, 0);
json_decref(root);
fprintf(ctx->nft->output.output_fp, "\n");
@@ -2049,7 +2058,7 @@ static void monitor_print_json(struct netlink_mon_handler *monh,
{
struct nft_ctx *nft = monh->ctx->nft;
- obj = json_pack("{s:o}", cmd, obj);
+ obj = nft_json_pack("{s:o}", cmd, obj);
if (nft_output_echo(&nft->output) && !nft->json_root) {
json_array_append_new(nft->json_echo, obj);
} else {
diff --git a/tests/shell/testcases/bogons/nft-j-f/Assertion__out_failed_assert b/tests/shell/testcases/bogons/nft-j-f/Assertion__out_failed_assert
new file mode 100644
index 00000000..f8ce0895
--- /dev/null
+++ b/tests/shell/testcases/bogons/nft-j-f/Assertion__out_failed_assert
@@ -0,0 +1,6 @@
+table ip test-ip {
+ quota htquota { comment "tŽst5" 5 kbytes
+ }
+}
+list ruleset
+add rule t c counter