Commit 26194bd6 authored by Ondrej Zajicek (work)'s avatar Ondrej Zajicek (work)
Browse files

Filter: Improved parse-time typechecks

parent 6fbcd891
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -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()')

+8 −53
Original line number Diff line number Diff line
@@ -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");
      }