diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-03-09 10:04:03 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-03-09 10:04:03 +0000 |
commit | 14cc2f2806c7b66992ca4a41d6f8da6020931194 (patch) | |
tree | f757e0b384ec5980da28790150f888e67f35fedb | |
parent | 17e8d87f2b9ece032bc4408b89918f0b366abc85 (diff) | |
download | mailfromd-14cc2f2806c7b66992ca4a41d6f8da6020931194.tar.gz mailfromd-14cc2f2806c7b66992ca4a41d6f8da6020931194.tar.bz2 |
Name clashes between constants and variables went unnoticed by the
compiler. Bug reported by Thomas Lynch.
Fix this and rename exception codes to minimize chances of such
clashes.
* src/symtab.c (lookup_or_install): Allow to search using state
masks.
(variable_or_constant_lookup): New function.
(constant_lookup): Return const struct constant *.
(constant_lookup_value): New function.
* src/lex.l (get_const): Remove.
(variable_or_const): New function.
* src/gram.y: Display warnings on a clash of constant and variable
names.
(VARIABLE): Change union type to var. Modify `variable' production
accordingly.
* src/mailfromd.h (_SYM_COUNT,SYM_MASK,SYM_BITS): New defines.
(constant_lookup): Return const struct constant *.
(constant_lookup_value): New function.
(variable_or_constant_lookup): New function.
* src/status.mfi: Prefix exception codes with `e_' to avoid name
clashes.
Provide backward-compatible constants.
* mflib/match_dnsbl.mf (match_dnsbl): Rename range to iprange to
avoid name clashes with the exception code.
Remove buggy conditions. Provide a correctly working replacement
for them if the m3 symbol `COMPAT_4_3' is defined.
* mflib/match_rhsbl.mf (match_rhsbl): Rename range to iprange to
avoid name clashes with the exception code.
Remove buggy conditions. Provide a correctly working replacement
for them if the m3 symbol `COMPAT_4_3' is defined.
* mflib/match_cidr.mf, mflib/safedb.mf4, tests/etc/catch.rc,
tests/etc/catch01.rc: Use new exception codes.
git-svn-id: file:///svnroot/mailfromd/branches/release_4_3_patches@1627 7a8a7f39-df28-0410-adc6-e0d955640f24
-rw-r--r-- | ChangeLog | 36 | ||||
-rw-r--r-- | mflib/match_cidr.mf | 4 | ||||
-rw-r--r-- | mflib/match_dnsbl.mf | 20 | ||||
-rw-r--r-- | mflib/match_rhsbl.mf | 12 | ||||
-rw-r--r-- | mflib/safedb.mf4 | 6 | ||||
-rw-r--r-- | src/gram.y | 50 | ||||
-rw-r--r-- | src/lex.l | 41 | ||||
-rw-r--r-- | src/mailfromd.h | 10 | ||||
-rw-r--r-- | src/status.mfi | 20 | ||||
-rw-r--r-- | src/symtab.c | 38 | ||||
-rw-r--r-- | tests/etc/catch.rc | 4 | ||||
-rw-r--r-- | tests/etc/catch01.rc | 6 |
12 files changed, 187 insertions, 60 deletions
@@ -1 +1,37 @@ +2008-03-09 Sergey Poznyakoff <gray@gnu.org.ua> + + Name clashes between constants and variables went unnoticed by the + compiler. Bug reported by Thomas Lynch. + Fix this and rename exception codes to minimize chances of such + clashes. + + * src/symtab.c (lookup_or_install): Allow to search using state + masks. + (variable_or_constant_lookup): New function. + (constant_lookup): Return const struct constant *. + (constant_lookup_value): New function. + * src/lex.l (get_const): Remove. + (variable_or_const): New function. + * src/gram.y: Display warnings on a clash of constant and variable + names. + (VARIABLE): Change union type to var. Modify `variable' production + accordingly. + * src/mailfromd.h (_SYM_COUNT,SYM_MASK,SYM_BITS): New defines. + (constant_lookup): Return const struct constant *. + (constant_lookup_value): New function. + (variable_or_constant_lookup): New function. + * src/status.mfi: Prefix exception codes with `e_' to avoid name + clashes. + Provide backward-compatible constants. + * mflib/match_dnsbl.mf (match_dnsbl): Rename range to iprange to + avoid name clashes with the exception code. + Remove buggy conditions. Provide a correctly working replacement + for them if the m3 symbol `COMPAT_4_3' is defined. + * mflib/match_rhsbl.mf (match_rhsbl): Rename range to iprange to + avoid name clashes with the exception code. + Remove buggy conditions. Provide a correctly working replacement + for them if the m3 symbol `COMPAT_4_3' is defined. + * mflib/match_cidr.mf, mflib/safedb.mf4, tests/etc/catch.rc, + tests/etc/catch01.rc: Use new exception codes. + 2008-03-01 Sergey Poznyakoff <gray@gnu.org.ua> diff --git a/mflib/match_cidr.mf b/mflib/match_cidr.mf index bb3470ad..24220ab4 100644 --- a/mflib/match_cidr.mf +++ b/mflib/match_cidr.mf @@ -1,3 +1,3 @@ /* Implementation of match_cidr call - Copyright (C) 2007 Sergey Poznyakoff + Copyright (C) 2007, 2008 Sergey Poznyakoff @@ -27,3 +27,3 @@ do else - throw invcidr "invalid CIDR (%cidr)" + throw e_invcidr "invalid CIDR (%cidr)" fi diff --git a/mflib/match_dnsbl.mf b/mflib/match_dnsbl.mf index 0621a98c..53603be5 100644 --- a/mflib/match_dnsbl.mf +++ b/mflib/match_dnsbl.mf @@ -2,2 +2,3 @@ Copyright (C) 2006, 2007 Jan Rafaj + Copyright (C) 2008 Sergey Poznyakoff @@ -21,11 +22,10 @@ -func match_dnsbl(string address, string zone, string range) +func match_dnsbl(string address, string zone, string iprange) returns number do - string rbl_ip - if %range = 'ANY' - set rbl_ip '127.0.0.0/8' + if %iprange = 'ANY' + set iprange '127.0.0.0/8' + m4_ifdef(`COMPAT_4_3',` else - set rbl_ip %range - if not %range matches '^([0-9]{1,3}\.){3}[0-9]{1,3}$' + if not %iprange matches `'''`^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$`'''` return 0 @@ -34,5 +34,5 @@ do - if not (%address matches '^([0-9]{1,3}\.){3}[0-9]{1,3}$' - and %address != %range) - return 0 + if not (%address matches `'''`^([0-9]{1,3}\.){3}[0-9]{1,3}$`'''` + and %address != %iprange) + return 0') fi @@ -41,3 +41,3 @@ do '^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$' - if match_cidr (resolve ("\4.\3.\2.\1", %zone), %rbl_ip) + if match_cidr (resolve ("\4.\3.\2.\1", %zone), %iprange) return 1 diff --git a/mflib/match_rhsbl.mf b/mflib/match_rhsbl.mf index 9b2a492a..d08f103b 100644 --- a/mflib/match_rhsbl.mf +++ b/mflib/match_rhsbl.mf @@ -2,2 +2,3 @@ Copyright (C) 2006, 2007 Jan Rafaj + Copyright (C) 2008 Sergey Poznyakoff @@ -20,7 +21,10 @@ #pragma regex push +extended -func match_rhsbl(string email, string zone, string range) +func match_rhsbl(string email, string zone, string iprange) returns number do - if not (%email matches '@.+$' - and %range matches '^([0-9]{1,3}\.){3}[0-9]{1,3}$') + if %iprange = 'ANY' + set iprange '127.0.0.0/8' + fi + if not (%email matches '@.+$'m4_ifdef(`COMPAT_4_3',` + and %iprange matches `'''`^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$'`'')) return 0 @@ -28,3 +32,3 @@ do - return match_cidr (resolve ((domainpart %email), %zone), %range) + return match_cidr (resolve ((domainpart %email), %zone), %iprange) done diff --git a/mflib/safedb.mf4 b/mflib/safedb.mf4 index f1d98b8a..822d3c7a 100644 --- a/mflib/safedb.mf4 +++ b/mflib/safedb.mf4 @@ -1,3 +1,3 @@ /* Safe DB I/O - Copyright (C) 2007 Sergey Poznyakoff + Copyright (C) 2007, 2008 Sergey Poznyakoff @@ -21,3 +21,3 @@ func safedbget(string name, string key ; string defval, number null) do - catch dbfailure + catch e_dbfailure do @@ -36,3 +36,3 @@ func safedbput(string name, string key, string value ; number null) do - catch dbfailure + catch e_dbfailure do @@ -2,3 +2,3 @@ /* This file is part of mailfromd. - Copyright (C) 2005, 2006, 2007 Sergey Poznyakoff + Copyright (C) 2005, 2006, 2007, 2008 Sergey Poznyakoff @@ -283,3 +283,3 @@ static void register_macro(enum smtp_state tag, const char *macro); %error-verbose -%expect 26 +%expect 27 @@ -343,3 +343,3 @@ static void register_macro(enum smtp_state tag, const char *macro); %token <literal> STRING CODE XCODE -%token <literal> SYMBOL VARIABLE IDENTIFIER +%token <literal> SYMBOL IDENTIFIER %token <number> ARG NUMBER BACKREF @@ -349,2 +349,4 @@ static void register_macro(enum smtp_state tag, const char *macro); %token <type> TYPE +%token <var> VARIABLE +%token BOGUS @@ -569,2 +571,14 @@ constdecl : CONST IDENTIFIER expr struct value value; + struct variable *pvar; + + /* FIXME: This is necessary because constants can be + referred to the same way as variables. */ + if (pvar = variable_lookup($2->text)) { + parse_warning(_("Constant name `%s' clashes with a variable name"), + $2->text); + parse_warning_locus(&pvar->locus, + _("This is the location of the " + "previous definition")); + } + if (optimization_level) @@ -1027,3 +1041,4 @@ value : STRING { - struct value *value_ptr = constant_lookup($1->text); + const struct value *value_ptr = + constant_lookup_value($1->text); if (value_ptr) @@ -1657,13 +1672,11 @@ variable : VARIABLE { - $$ = variable_lookup($1->text); - if (!$$) { - parse_error(_("Variable %s is not defined"), - $1->text); - YYERROR; - } - add_xref($$, get_locus()); + add_xref($1, get_locus()); } - ; + | BOGUS + { + YYERROR; + } + ; -catch : CATCH catchlist DO +catch : CATCH catchlist DO { $<tie_in>$ = inner_context; @@ -3442,2 +3455,3 @@ vardecl(const char *name, data_type_t type, storage_class_t sc, struct variable *var; + const struct constant *cptr; @@ -3518,2 +3532,12 @@ vardecl(const char *name, data_type_t type, storage_class_t sc, + /* FIXME: This is necessary because constants can be + referred to the same way as variables. */ + if (cptr = constant_lookup(name)) { + parse_warning(_("Variable name `%s' clashes with a constant name"), + name); + parse_warning_locus(&cptr->locus, + _("This is the location of the " + "previous definition")); + } + var->type = type; @@ -2,3 +2,3 @@ /* This file is part of mailfromd. - Copyright (C) 2005, 2006, 2007 Sergey Poznyakoff + Copyright (C) 2005, 2006, 2007, 2008 Sergey Poznyakoff @@ -87,6 +87,22 @@ keyword(int kw) static int -get_const(const char *name) +variable_or_const() { - struct value *value_ptr; - if (value_ptr = constant_lookup(name)) { + union { + struct variable *vptr; + struct constant *cptr; + } v; + const struct value *value_ptr; + + switch (variable_or_constant_lookup(yylval.literal->text, &v)) { + case SYM_UNDEF: + parse_error(_("Variable %s is not defined"), + yylval.literal->text); + return BOGUS; + + case SYM_VARIABLE: + yylval.var = v.vptr; + return VARIABLE; + + case SYM_CONSTANT: + value_ptr = &v.cptr->value; switch (value_ptr->type) { @@ -104,4 +120,4 @@ get_const(const char *name) } - return 0; } + @@ -261,15 +277,10 @@ end return keyword(KW_END); <INITIAL,ONBLOCK,ML,CML,STR>\%{IDENT} { - int rc; string(yytext + 1, yyleng - 1); - if ((rc = get_const(yylval.literal->text)) != 0) - return rc; - else - return VARIABLE; } + return variable_or_const(); +} <INITIAL,ONBLOCK,ML,CML,STR>\%\{{IDENT}\} { - int rc; string(yytext + 2, yyleng - 3); - if ((rc = get_const(yylval.literal->text)) != 0) - return rc; - else - return VARIABLE; } + return variable_or_const(); +} + /* Positional arguments */ diff --git a/src/mailfromd.h b/src/mailfromd.h index 20e2d360..54449c43 100644 --- a/src/mailfromd.h +++ b/src/mailfromd.h @@ -1,3 +1,3 @@ /* This file is part of mailfromd. - Copyright (C) 2005, 2006, 2007 Sergey Poznyakoff + Copyright (C) 2005, 2006, 2007, 2008 Sergey Poznyakoff @@ -589,2 +589,5 @@ struct constant { #define SYM_CONSTANT 5 /* A constant */ +#define _SYM_COUNT 6 +#define SYM_MASK(n) (1<<(n)) +#define SYM_BITS SYM_MASK(_SYM_COUNT) @@ -630,2 +633,4 @@ void defer_initialize_variable(char *arg, char *val); +int variable_or_constant_lookup(const char *name, void **dptr); + struct function *function_install(const char *name, @@ -638,3 +643,4 @@ struct literal *literal_lookup(const char *text); void define_constant(const char *name, struct value *value, struct locus *loc); -struct value *constant_lookup(const char *name); +const struct constant *constant_lookup(const char *name); +const struct value *constant_lookup_value(const char *name); diff --git a/src/status.mfi b/src/status.mfi index 6218bcd7..40ac06fb 100644 --- a/src/status.mfi +++ b/src/status.mfi @@ -10,2 +10,20 @@ const FAMILY_INET 2 -%{const %NAME %CODE%} +%{const e_%NAME %CODE%} + +# Backward-compatible definitions +const success e_success +const not_found e_not_found +const failure e_failure +const temp_failure e_temp_failure +const ston_conv e_ston_conv +const divzero e_divzero +const regcomp e_regcomp +const invip e_invip +const invcidr e_invcidr +const invtime e_invtime +const dbfailure e_dbfailure +const range e_range +const url e_url +const noresolve e_noresolve +const ioerr e_ioerr +const macroundef e_macroundef diff --git a/src/symtab.c b/src/symtab.c index c9c31194..cab45cc6 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -1,3 +1,3 @@ /* This file is part of mailfromd. - Copyright (C) 2006, 2007 Sergey Poznyakoff + Copyright (C) 2006, 2007, 2008 Sergey Poznyakoff @@ -174,3 +174,4 @@ lookup_or_install(int state, const char *name, int install) unsigned i, pos; - + struct symtab *foundp = NULL; + if (!symtable) { @@ -189,2 +190,7 @@ lookup_or_install(int state, const char *name, int install) return &symtable[i]; + else if ((state & SYM_BITS) + && (SYM_MASK(symtable[i].state) & state) + && strcmp(symtable[i].vp->name, name) == 0) + foundp = &symtable[i]; + if (++i >= hash_size[hash_num]) @@ -194,4 +200,7 @@ lookup_or_install(int state, const char *name, int install) } + + if ((state & SYM_BITS) && foundp) + return foundp; - if (!install || state == SYM_UNDEF) + if (!install || (state == SYM_UNDEF || (state & SYM_BITS))) return NULL; @@ -400,2 +409,14 @@ variable_lookup(const char *name) +int +variable_or_constant_lookup(const char *name, void **dptr) +{ + struct symtab *sp = lookup_or_install( + SYM_BITS|SYM_MASK(SYM_VARIABLE)|SYM_MASK(SYM_CONSTANT), + name, 0); + if (!sp) + return SYM_UNDEF; + *dptr = sp->vp; + return sp->state; +} + @@ -469,3 +490,3 @@ define_constant(const char *name, struct value *value, struct locus *locus) -struct value * +const struct constant * constant_lookup(const char *name) @@ -473,3 +494,10 @@ constant_lookup(const char *name) struct symtab *sp = lookup_or_install(SYM_CONSTANT, name, 0); - return sp ? &sp->vp->constant.value : NULL; + return sp ? &sp->vp->constant : NULL; +} + +const struct value * +constant_lookup_value(const char *name) +{ + const struct constant *cptr = constant_lookup(name); + return cptr ? &cptr->value : NULL; } diff --git a/tests/etc/catch.rc b/tests/etc/catch.rc index 70be9596..1b91a3e4 100644 --- a/tests/etc/catch.rc +++ b/tests/etc/catch.rc @@ -1,3 +1,3 @@ /* This file is part of Mailfromd -*- mfl -*- - Copyright (C) 2006, 2007 Sergey Poznyakoff + Copyright (C) 2006, 2007, 2008 Sergey Poznyakoff @@ -23,3 +23,3 @@ prog envfrom do - catch invip or invcidr + catch e_invip or e_invcidr do diff --git a/tests/etc/catch01.rc b/tests/etc/catch01.rc index 6820be96..966365b7 100644 --- a/tests/etc/catch01.rc +++ b/tests/etc/catch01.rc @@ -1,3 +1,3 @@ /* This file is part of Mailfromd -*- mfl -*- - Copyright (C) 2006, 2007 Sergey Poznyakoff + Copyright (C) 2006, 2007, 2008 Sergey Poznyakoff @@ -23,3 +23,3 @@ func safe_cidr(s,s) returns n do - catch invip + catch e_invip do @@ -33,3 +33,3 @@ prog envfrom do - catch invip or invcidr + catch e_invip or e_invcidr do |