diff options
author | Patrick McHardy <kaber@trash.net> | 2013-04-22 18:50:44 +0200 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2013-04-22 18:50:44 +0200 |
commit | 2e27ad8122fe20db802e1c7bb9d5f4ad6cd23665 (patch) | |
tree | 0ee3533c6a45d1f00226eaea77255033f297c727 | |
parent | e1538f3e32a440fd8896cec073a3182d09f6b9b0 (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.c | 9 | ||||
-rw-r--r-- | src/evaluate.c | 14 |
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; |