aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2008-03-09 10:04:03 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2008-03-09 10:04:03 +0000
commit14cc2f2806c7b66992ca4a41d6f8da6020931194 (patch)
treef757e0b384ec5980da28790150f888e67f35fedb
parent17e8d87f2b9ece032bc4408b89918f0b366abc85 (diff)
downloadmailfromd-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--ChangeLog36
-rw-r--r--mflib/match_cidr.mf4
-rw-r--r--mflib/match_dnsbl.mf20
-rw-r--r--mflib/match_rhsbl.mf12
-rw-r--r--mflib/safedb.mf46
-rw-r--r--src/gram.y50
-rw-r--r--src/lex.l41
-rw-r--r--src/mailfromd.h10
-rw-r--r--src/status.mfi20
-rw-r--r--src/symtab.c38
-rw-r--r--tests/etc/catch.rc4
-rw-r--r--tests/etc/catch01.rc6
12 files changed, 187 insertions, 60 deletions
diff --git a/ChangeLog b/ChangeLog
index f1ecc135..9abbf87e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/src/gram.y b/src/gram.y
index 7732007f..bb68ded5 100644
--- a/src/gram.y
+++ b/src/gram.y
@@ -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;
diff --git a/src/lex.l b/src/lex.l
index 7b043bf1..c33f2a62 100644
--- a/src/lex.l
+++ b/src/lex.l
@@ -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

Return to:

Send suggestions and report system problems to the System administrator.