diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 99785057..35b590bb 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -646,7 +646,7 @@ cf_walk_symbols(struct config *cf, struct symbol *sym, int *pos) char * cf_symbol_class_name(struct symbol *sym) { - if ((sym->class & 0xff00) == SYM_CONSTANT) + if (cf_symbol_is_constant(sym)) return "constant"; switch (sym->class) diff --git a/conf/conf.h b/conf/conf.h index fa14d7b5..799873d2 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -149,6 +149,10 @@ void cf_pop_scope(void); struct symbol *cf_walk_symbols(struct config *cf, struct symbol *sym, int *pos); char *cf_symbol_class_name(struct symbol *sym); +static inline int cf_symbol_is_constant(struct symbol *sym) +{ return (sym->class & 0xff00) == SYM_CONSTANT; } + + /* Parser */ int cf_parse(void); diff --git a/filter/config.Y b/filter/config.Y index 04acfbab..e50e75ca 100644 --- a/filter/config.Y +++ b/filter/config.Y @@ -25,6 +25,23 @@ static inline u32 pair_b(u32 p) { return p & 0xFFFF; } * to the last item in a list (right ptr). For convenience, even items * are handled as one-item lists. Lists are merged by f_merge_items(). */ +static int +f_valid_set_type(int type) +{ + switch (type) + { + case T_INT: + case T_PAIR: + case T_QUAD: + case T_ENUM: + case T_IP: + case T_EC: + return 1; + + default: + return 0; + } +} static inline struct f_tree * f_new_item(struct f_val from, struct f_val to) @@ -473,10 +490,19 @@ fipa: */ set_atom: - expr { $$.type = T_INT; $$.val.i = $1; } + NUM { $$.type = T_INT; $$.val.i = $1; } | RTRID { $$.type = T_QUAD; $$.val.i = $1; } | fipa { $$ = $1; } | ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); } + | '(' term ')' { + $$ = f_eval($2, cfg_mem); + if (!f_valid_set_type($$.type)) cf_error("Set-incompatible type"); + } + | SYM { + if (!cf_symbol_is_constant($1)) cf_error("%s: constant expected", $1->name); + if (!f_valid_set_type(SYM_TYPE($1))) cf_error("%s: set-incompatible type", $1->name); + $$ = *(struct f_val *)($1->def); + } ; switch_atom: diff --git a/filter/test.conf b/filter/test.conf index 84faca0e..a99d0a51 100644 --- a/filter/test.conf +++ b/filter/test.conf @@ -13,6 +13,9 @@ define '1a-a1' = (20+10); define one = 1; define ten = 10; +define p23 = (2, 3); +define ip1222 = 1.2.2.2; + function onef(int a) { return 1; @@ -98,7 +101,7 @@ eclist el2; print "Should be true: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 3 ~ p2, " ", p2 ~ [2, 10..20], " ", p2 ~ [4, 10..20]; print "4 = ", p2.len; p2 = prepend( p2, 5 ); - print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2, " ", p2 ~ [8, 10..20],; + print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2, " ", p2 ~ [8, ten..(2*ten)]; print "Should be true: ", p2 ~ / ? 4 3 2 1 /, " ", p2, " ", / ? 4 3 2 1 /; print "Should be true: ", p2 ~ [= * 4 3 * 1 =], " ", p2, " ", [= * 4 3 * 1 =]; print "Should be true: ", p2 ~ [= (3+2) (2*2) 3 2 1 =], " ", p2 ~ mkpath(5, 4); @@ -124,7 +127,7 @@ eclist el2; print "Should be always true: ", l ~ [(*,*)]; l = add( l, (2,one+2) ); print "Community list (1,2) (2,3) ", l; - print "Should be true: ", (2,3) ~ l, " ", l ~ [(1,*)], " ", l ~ [(2,3)]," ", l ~ [(2,2..3)], " ", l ~ [(1,1..2)], " ", l ~ [(1,1)..(1,2)]; + print "Should be true: ", (2,3) ~ l, " ", l ~ [(1,*)], " ", l ~ [p23]," ", l ~ [(2,2..3)], " ", l ~ [(1,1..2)], " ", l ~ [(1,1)..(1,2)]; l = add( l, (2,5) ); l = add( l, (5,one) ); l = add( l, (6,one) ); @@ -361,7 +364,7 @@ string st; if ( b = true ) then print "Testing bool comparison b = true: ", b; else { print "*** FAIL: TRUE test failed" ; quitbird; } - ips = [ 1.1.1.0 .. 1.1.1.255, 1.2.2.2]; + ips = [ 1.1.1.0 .. 1.1.1.255, ip1222]; print "Testing IP sets: "; print ips; print " must be true: ", 1.1.1.0 ~ ips, ",", 1.1.1.100 ~ ips, ",", 1.2.2.2 ~ ips;