You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by bi...@apache.org on 2018/03/08 06:41:57 UTC
svn commit: r1826179 - in /spamassassin:
branches/3.4/lib/Mail/SpamAssassin/Conf/Parser.pm
trunk/lib/Mail/SpamAssassin/Conf/Parser.pm
Author: billcole
Date: Thu Mar 8 06:41:57 2018
New Revision: 1826179
URL: http://svn.apache.org/viewvc?rev=1826179&view=rev
Log:
Fix for Bug #7557
Modified:
spamassassin/branches/3.4/lib/Mail/SpamAssassin/Conf/Parser.pm
spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm
Modified: spamassassin/branches/3.4/lib/Mail/SpamAssassin/Conf/Parser.pm
URL: http://svn.apache.org/viewvc/spamassassin/branches/3.4/lib/Mail/SpamAssassin/Conf/Parser.pm?rev=1826179&r1=1826178&r2=1826179&view=diff
==============================================================================
--- spamassassin/branches/3.4/lib/Mail/SpamAssassin/Conf/Parser.pm (original)
+++ spamassassin/branches/3.4/lib/Mail/SpamAssassin/Conf/Parser.pm Thu Mar 8 06:41:57 2018
@@ -592,7 +592,7 @@ sub cond_clause_can_or_has {
} elsif ($method =~ /^(.*)::([^:]+)$/) {
no strict "refs";
my($module, $meth) = ($1, $2);
- return 1 if UNIVERSAL::can($module,$meth) &&
+ return 1 if $module->can($meth) &&
( $fn_name eq 'has' || &{$method}() );
} else {
$self->lint_warn("bad 'if' line, cannot find '::' in $fn_name($method), ".
@@ -1179,25 +1179,25 @@ sub add_test {
my $conf = $self->{conf};
# Don't allow invalid names ...
- if ($name !~ /^\D\w*$/) {
+ if ($name !~ /^[_[:alpha:]]\w*$/) {
$self->lint_warn("config: error: rule '$name' has invalid characters ".
"(not Alphanumeric + Underscore + starting with a non-digit)\n", $name);
return;
}
- # Also set a hard limit for ALL rules (rule names longer than 242
+ # Also set a hard limit for ALL rules (rule names longer than 40
# characters throw warnings). Check this separately from the above
# pattern to avoid vague error messages.
- if (length $name > 200) {
- $self->lint_warn("config: error: rule '$name' is way too long ".
+ if (length $name > 100) {
+ $self->lint_warn("config: error: rule '$name' is too long ".
"(recommended maximum length is 22 characters)\n", $name);
return;
}
# Warn about, but use, long rule names during --lint
if ($conf->{lint_rules}) {
- if (length($name) > 50 && $name !~ /^__/ && $name !~ /^T_/) {
- $self->lint_warn("config: warning: rule name '$name' is over 50 chars ".
+ if (length($name) > 40 && $name !~ /^__/ && $name !~ /^T_/) {
+ $self->lint_warn("config: warning: rule name '$name' is over 40 chars ".
"(recommended maximum length is 22 characters)\n", $name);
}
}
@@ -1287,8 +1287,14 @@ sub add_regression_test {
sub is_meta_valid {
my ($self, $name, $rule) = @_;
+ # $meta is a degenerate translation of the rule, replacing all variables (i.e. rule names) with 0.
my $meta = '';
$rule = untaint_var($rule); # must be careful below
+ # Bug #7557 code injection
+ if ( $rule =~ /\S(::|->)\S/ ) {
+ warn("is_meta_valid: Bogus rule $name: $rule") ;
+ return 0;
+ }
# Lex the rule into tokens using a rather simple RE method ...
my $lexer = ARITH_EXPRESSION_LEXER;
@@ -1300,16 +1306,20 @@ sub is_meta_valid {
}
# Go through each token in the meta rule
foreach my $token (@tokens) {
- # Numbers can't be rule names
- if ($token !~ /^[A-Za-z_][A-Za-z0-9_]*\z/s) {
+ # If the token is a syntactically legal rule name, make it zero
+ if ($token =~ /^[_[:alpha:]]\w+\z/s) {
+ $meta .= "0 ";
+ }
+ # if it is a number or a string of 1 or 2 punctuation characters (i.e. operators) tack it onto the degenerate rule
+ elsif ( $token =~ /^(\d+|[[:punct:]]{1,2})\z/s ) {
$meta .= "$token ";
}
- # Zero will probably cause more errors
+ # WTF is it? Just warn, for now. Bug #7557
else {
- $meta .= "0 ";
+ $self->lint_warn("config: Strange rule token: $token", $name);
+ $meta .= "$token ";
}
}
-
my $evalstr = 'my $x = ' . $meta . '; 1;';
if (eval $evalstr) {
return 1;
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm?rev=1826179&r1=1826178&r2=1826179&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Conf/Parser.pm Thu Mar 8 06:41:57 2018
@@ -592,7 +592,7 @@ sub cond_clause_can_or_has {
} elsif ($method =~ /^(.*)::([^:]+)$/) {
no strict "refs";
my($module, $meth) = ($1, $2);
- return 1 if UNIVERSAL::can($module,$meth) &&
+ return 1 if $module->can($meth) &&
( $fn_name eq 'has' || &{$method}() );
} else {
$self->lint_warn("bad 'if' line, cannot find '::' in $fn_name($method), ".
@@ -1179,25 +1179,25 @@ sub add_test {
my $conf = $self->{conf};
# Don't allow invalid names ...
- if ($name !~ /^\D\w*$/) {
+ if ($name !~ /^[_[:alpha:]]\w*$/) {
$self->lint_warn("config: error: rule '$name' has invalid characters ".
"(not Alphanumeric + Underscore + starting with a non-digit)\n", $name);
return;
}
- # Also set a hard limit for ALL rules (rule names longer than 242
+ # Also set a hard limit for ALL rules (rule names longer than 40
# characters throw warnings). Check this separately from the above
# pattern to avoid vague error messages.
- if (length $name > 200) {
- $self->lint_warn("config: error: rule '$name' is way too long ".
+ if (length $name > 100) {
+ $self->lint_warn("config: error: rule '$name' is too long ".
"(recommended maximum length is 22 characters)\n", $name);
return;
}
# Warn about, but use, long rule names during --lint
if ($conf->{lint_rules}) {
- if (length($name) > 50 && $name !~ /^__/ && $name !~ /^T_/) {
- $self->lint_warn("config: warning: rule name '$name' is over 50 chars ".
+ if (length($name) > 40 && $name !~ /^__/ && $name !~ /^T_/) {
+ $self->lint_warn("config: warning: rule name '$name' is over 40 chars ".
"(recommended maximum length is 22 characters)\n", $name);
}
}
@@ -1287,8 +1287,14 @@ sub add_regression_test {
sub is_meta_valid {
my ($self, $name, $rule) = @_;
+ # $meta is a degenerate translation of the rule, replacing all variables (i.e. rule names) with 0.
my $meta = '';
$rule = untaint_var($rule); # must be careful below
+ # Bug #7557 code injection
+ if ( $rule =~ /\S(::|->)\S/ ) {
+ warn("is_meta_valid: Bogus rule $name: $rule") ;
+ return 0;
+ }
# Lex the rule into tokens using a rather simple RE method ...
my $lexer = ARITH_EXPRESSION_LEXER;
@@ -1300,16 +1306,20 @@ sub is_meta_valid {
}
# Go through each token in the meta rule
foreach my $token (@tokens) {
- # Numbers can't be rule names
- if ($token !~ /^[A-Za-z_][A-Za-z0-9_]*\z/s) {
+ # If the token is a syntactically legal rule name, make it zero
+ if ($token =~ /^[_[:alpha:]]\w+\z/s) {
+ $meta .= "0 ";
+ }
+ # if it is a number or a string of 1 or 2 punctuation characters (i.e. operators) tack it onto the degenerate rule
+ elsif ( $token =~ /^(\d+|[[:punct:]]{1,2})\z/s ) {
$meta .= "$token ";
}
- # Zero will probably cause more errors
+ # WTF is it? Just warn, for now. Bug #7557
else {
- $meta .= "0 ";
+ $self->lint_warn("config: Strange rule token: $token", $name);
+ $meta .= "$token ";
}
}
-
my $evalstr = 'my $x = ' . $meta . '; 1;';
if (eval $evalstr) {
return 1;