summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2019-10-23 22:53:23 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2019-11-05 15:28:47 +0100
commit26194bd684b2926740a74ebdfe73e6afc3c145b6 (patch)
tree5f26679bffb2cd351130264ce6f21baff19ede19
parent6fbcd8914aa2b0e0f50c6f20a15cd6eb1ba44497 (diff)
Filter: Improved parse-time typechecks
-rw-r--r--filter/decl.m47
-rw-r--r--filter/f-inst.c61
2 files changed, 12 insertions, 56 deletions
diff --git a/filter/decl.m4 b/filter/decl.m4
index 981d09a9..e7d8c1d8 100644
--- a/filter/decl.m4
+++ b/filter/decl.m4
@@ -160,12 +160,13 @@ FID_HIC(,[[
')
# Some arguments need to check their type. After that, ARG_ANY is called.
-m4_define(ARG, `ARG_ANY($1)
+m4_define(ARG, `ARG_ANY($1) ARG_TYPE($1,$2)')
+m4_define(ARG_TYPE, `
FID_NEW_BODY()m4_dnl
-if (f$1->type && (f$1->type != $2))
+if (f$1->type && (f$1->type != ($2)))
cf_error("Argument $1 of instruction %s must be of type $2, got 0x%02x", f_instruction_name(what->fi_code), f$1->type);
FID_INTERPRET_EXEC()m4_dnl
-if (v$1.type != $2)
+if (v$1.type != ($2))
runtime("Argument $1 of instruction %s must be of type $2, got 0x%02x", f_instruction_name(what->fi_code), v$1.type)m4_dnl
FID_INTERPRET_BODY()')
diff --git a/filter/f-inst.c b/filter/f-inst.c
index 0bc48b3a..57b6f011 100644
--- a/filter/f-inst.c
+++ b/filter/f-inst.c
@@ -104,7 +104,7 @@
* m4_dnl (103) [[ put it here ]]
* m4_dnl ...
* m4_dnl if (all arguments are constant)
- * m4_dnl (108) [[ put it here ]]
+ * m4_dnl (108) [[ put it here ]]
* m4_dnl }
* m4_dnl For writing directly to constructor argument list, use FID_NEW_ARGS.
* m4_dnl For computing something in constructor (103), use FID_NEW_BODY.
@@ -416,18 +416,7 @@
NEVER_CONSTANT;
ARG_ANY(1);
SYMBOL;
-
- if ((sym->class != (SYM_VARIABLE | v1.type)) && (v1.type != T_VOID))
- {
- /* IP->Quad implicit conversion */
- if ((sym->class == (SYM_VARIABLE | T_QUAD)) && val_is_ip4(&v1))
- v1 = (struct f_val) {
- .type = T_QUAD,
- .val.i = ipa_to_u32(v1.val.ip),
- };
- else
- runtime( "Assigning to variable of incompatible type" );
- }
+ ARG_TYPE(1, sym->class & 0xff);
fstk->vstk[curline.vbase + sym->offset] = v1;
}
@@ -520,8 +509,7 @@
ACCESS_RTE;
ARG_ANY(1);
STATIC_ATTR;
- if (sa.f_type != v1.type)
- runtime( "Attempt to set static attribute to incompatible type" );
+ ARG_TYPE(1, sa.f_type);
f_rta_cow(fs);
{
@@ -666,6 +654,7 @@
ACCESS_EATTRS;
ARG_ANY(1);
DYNAMIC_ATTR;
+ ARG_TYPE(1, da.f_type);
{
struct ea_list *l = lp_alloc(fs->pool, sizeof(struct ea_list) + sizeof(eattr));
@@ -678,20 +667,7 @@
switch (da.type) {
case EAF_TYPE_INT:
- if (v1.type != da.f_type)
- runtime( "Setting int attribute to non-int value" );
- l->attrs[0].u.data = v1.val.i;
- break;
-
case EAF_TYPE_ROUTER_ID:
- /* IP->Quad implicit conversion */
- if (val_is_ip4(&v1)) {
- l->attrs[0].u.data = ipa_to_u32(v1.val.ip);
- break;
- }
- /* T_INT for backward compatibility */
- if ((v1.type != T_QUAD) && (v1.type != T_INT))
- runtime( "Setting quad attribute to non-quad value" );
l->attrs[0].u.data = v1.val.i;
break;
@@ -699,9 +675,7 @@
runtime( "Setting opaque attribute is not allowed" );
break;
- case EAF_TYPE_IP_ADDRESS:
- if (v1.type != T_IP)
- runtime( "Setting ip attribute to non-ip value" );
+ case EAF_TYPE_IP_ADDRESS:;
int len = sizeof(ip_addr);
struct adata *ad = lp_alloc(fs->pool, sizeof(struct adata) + len);
ad->length = len;
@@ -710,14 +684,13 @@
break;
case EAF_TYPE_AS_PATH:
- if (v1.type != T_PATH)
- runtime( "Setting path attribute to non-path value" );
+ case EAF_TYPE_INT_SET:
+ case EAF_TYPE_EC_SET:
+ case EAF_TYPE_LC_SET:
l->attrs[0].u.ptr = v1.val.ad;
break;
case EAF_TYPE_BITFIELD:
- if (v1.type != T_BOOL)
- runtime( "Setting bit in bitfield attribute to non-bool value" );
{
/* First, we have to find the old value */
eattr *e = ea_find(*fs->eattrs, da.ea_code);
@@ -730,24 +703,6 @@
}
break;
- case EAF_TYPE_INT_SET:
- if (v1.type != T_CLIST)
- runtime( "Setting clist attribute to non-clist value" );
- l->attrs[0].u.ptr = v1.val.ad;
- break;
-
- case EAF_TYPE_EC_SET:
- if (v1.type != T_ECLIST)
- runtime( "Setting eclist attribute to non-eclist value" );
- l->attrs[0].u.ptr = v1.val.ad;
- break;
-
- case EAF_TYPE_LC_SET:
- if (v1.type != T_LCLIST)
- runtime( "Setting lclist attribute to non-lclist value" );
- l->attrs[0].u.ptr = v1.val.ad;
- break;
-
default:
bug("Unknown dynamic attribute type");
}