]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Filter: Improved parse-time typechecks
authorOndrej Zajicek (work) <santiago@crfreenet.org>
Wed, 23 Oct 2019 20:53:23 +0000 (22:53 +0200)
committerOndrej Zajicek (work) <santiago@crfreenet.org>
Tue, 5 Nov 2019 14:28:47 +0000 (15:28 +0100)
filter/decl.m4
filter/f-inst.c

index 981d09a9e9d90b82800e39a713aea993e3757e00..e7d8c1d829015a43fed9c4658d90dc7fc2d8db47 100644 (file)
@@ -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()')
 
index 0bc48b3a86f23d012f5c4a67686c3679b6ec9fef..57b6f011745004617d1be5f5cc6e158de0c8f0fc 100644 (file)
  *     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.
     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;
   }
     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);
     {
     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));
 
 
       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;
 
        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;
        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);
        }
        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");
       }