summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2013-04-22 18:50:44 +0200
committerPatrick McHardy <kaber@trash.net>2013-04-22 18:50:44 +0200
commit2e27ad8122fe20db802e1c7bb9d5f4ad6cd23665 (patch)
tree0ee3533c6a45d1f00226eaea77255033f297c727
parente1538f3e32a440fd8896cec073a3182d09f6b9b0 (diff)
expr: catch missing and excess elements in concatenations
# nft -nn filter output ip daddr . tcp dport . tcp dport { 192.168.0.1 . ssh } <cmdline>:1:50-66: Error: datatype mismatch, expected concatenation of (IPv4 address, internet network service, internet network service), expression has type concatenation of (IPv4 address, internet network service) filter output ip daddr . tcp dport . tcp dport { 192.168.0.1 . ssh } ^^^^^^^^^^^^^^^^^ # nft -nn filter output ip daddr . tcp dport . tcp dport { 192.168.0.1 . ssh . ssh . ssh} <cmdline>:1:76-78: Error: unexpected concat component, expecting concatenation of (IPv4 address, internet network service, internet network service) filter output ip daddr . tcp dport . tcp dport { 192.168.0.1 . ssh . ssh . ssh} ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^ Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--src/datatype.c9
-rw-r--r--src/evaluate.c14
2 files changed, 19 insertions, 4 deletions
diff --git a/src/datatype.c b/src/datatype.c
index 3c17e929..2cb937f5 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -662,20 +662,23 @@ const struct datatype *concat_type_alloc(const struct expr *expr)
{
struct datatype *dtype;
struct expr *i;
- char desc[256] = "concatenation of ";
- unsigned int type = 0;
+ char desc[256] = "concatenation of (";
+ unsigned int type = 0, size = 0;
list_for_each_entry(i, &expr->expressions, list) {
- if (type != 0)
+ if (size != 0)
strncat(desc, ", ", sizeof(desc) - strlen(desc) - 1);
strncat(desc, i->dtype->desc, sizeof(desc) - strlen(desc) - 1);
type <<= 8;
type |= i->dtype->type;
+ size++;
}
+ strncat(desc, ")", sizeof(desc) - strlen(desc) - 1);
dtype = xzalloc(sizeof(*dtype));
dtype->type = type;
+ dtype->size = size;
dtype->desc = xstrdup(desc);
dtype->parse = concat_type_parse;
diff --git a/src/evaluate.c b/src/evaluate.c
index bf169321..6f90f54f 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -585,13 +585,19 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr)
{
const struct datatype *dtype = ctx->ectx.dtype, *tmp;
unsigned int type = dtype ? dtype->type : 0;
+ int off = dtype ? dtype->size: 0;
unsigned int flags = EXPR_F_CONSTANT | EXPR_F_SINGLETON;
struct expr *i, *next;
unsigned int n;
n = 1;
list_for_each_entry_safe(i, next, &(*expr)->expressions, list) {
- tmp = datatype_lookup((type >> 8 * ((*expr)->size - n)) & 0xff);
+ if (dtype && off == 0)
+ return expr_binary_error(ctx, i, *expr,
+ "unexpected concat component, "
+ "expecting %s",
+ dtype->desc);
+ tmp = datatype_lookup((type >> 8 * --off) & 0xff);
expr_set_context(&ctx->ectx, tmp, tmp->size);
if (list_member_evaluate(ctx, &i) < 0)
@@ -604,6 +610,12 @@ static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr)
(*expr)->flags |= flags;
(*expr)->dtype = concat_type_alloc(*expr);
+ if (off > 0)
+ return expr_error(ctx, *expr,
+ "datatype mismatch, expected %s, "
+ "expression has type %s",
+ dtype->desc, (*expr)->dtype->desc);
+
expr_set_context(&ctx->ectx, (*expr)->dtype, (*expr)->len);
return 0;