You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by he...@apache.org on 2019/08/12 09:12:40 UTC
svn commit: r1864949 - in /spamassassin/trunk: UPGRADE
lib/Mail/SpamAssassin/Logger.pm lib/Mail/SpamAssassin/Logger/File.pm
lib/Mail/SpamAssassin/Logger/Stderr.pm
lib/Mail/SpamAssassin/Logger/Syslog.pm spamd/spamd.raw
Author: hege
Date: Mon Aug 12 09:12:40 2019
New Revision: 1864949
URL: http://svn.apache.org/viewvc?rev=1864949&view=rev
Log:
- Bug 6583: Add new escape option to Logger::add() and Logger/*.pm modules and start using it
- Fix duplicate log supressor logic to escape duplicated message properly
Modified:
spamassassin/trunk/UPGRADE
spamassassin/trunk/lib/Mail/SpamAssassin/Logger.pm
spamassassin/trunk/lib/Mail/SpamAssassin/Logger/File.pm
spamassassin/trunk/lib/Mail/SpamAssassin/Logger/Stderr.pm
spamassassin/trunk/lib/Mail/SpamAssassin/Logger/Syslog.pm
spamassassin/trunk/spamd/spamd.raw
Modified: spamassassin/trunk/UPGRADE
URL: http://svn.apache.org/viewvc/spamassassin/trunk/UPGRADE?rev=1864949&r1=1864948&r2=1864949&view=diff
==============================================================================
--- spamassassin/trunk/UPGRADE (original)
+++ spamassassin/trunk/UPGRADE Mon Aug 12 09:12:40 2019
@@ -2,6 +2,12 @@
Note for Users Upgrading to SpamAssassin 4.0.0
----------------------------------------------
+- All log output (stderr, file, syslog) is now binary safe,
+ non-ascii characters are escaped as \x{XX} or \x{XXXX}, backslashes escaped
+ as \\. Whitespace is not normalized anymore like in pre-4.0 versions.
+
+- API: Logger::add() has new optional 'escape' parameter.
+
- API: New $pms->add_uri_detail_list() function. Also new uri_detail_list
types: unlinked, schemeless
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Logger.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Logger.pm?rev=1864949&r1=1864948&r2=1864949&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Logger.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Logger.pm Mon Aug 12 09:12:40 2019
@@ -74,7 +74,8 @@ $LOG_SA{facility} = {}; # no dbg facili
# always log to stderr initially
use Mail::SpamAssassin::Logger::Stderr;
-$LOG_SA{method}->{stderr} = Mail::SpamAssassin::Logger::Stderr->new();
+$LOG_SA{method}->{stderr} =
+ Mail::SpamAssassin::Logger::Stderr->new(escape => 1);
=head1 METHODS
@@ -164,7 +165,7 @@ sub log_message {
# don't log them -- this is caller 0, the use'ing package is 1, the eval is 2
my @caller = caller 2;
return if (defined $caller[3] && defined $caller[0] &&
- $caller[3] =~ /^\(eval\)$/ &&
+ $caller[3] eq '(eval)' &&
$caller[0] =~ m#^Mail::SpamAssassin(?:$|::)#);
}
@@ -188,33 +189,44 @@ sub log_message {
} else {
if ($LOG_DUPCNT >= $LOG_DUPMIN) {
$LOG_DUPCNT -= $LOG_DUPMIN - 1;
- my $dupmsg = $LOG_DUPCNT > 1 ? " [... logline repeated $LOG_DUPCNT times]" : "";
- while (my ($name, $object) = each %{ $LOG_SA{method} }) {
- $object->log_message($level, "$LOG_DUPLINE$dupmsg", $LOG_DUPTIME);
+ if ($LOG_DUPCNT > 1) {
+ _log_message($level,
+ "$LOG_DUPLINE [... logline repeated $LOG_DUPCNT times]",
+ $LOG_DUPTIME);
+ } else {
+ _log_message($level, $LOG_DUPLINE, $LOG_DUPTIME);
}
}
$LOG_DUPCNT = 0;
$LOG_DUPLINE = $message;
}
+ _log_message($level, $message, $now);
+
+ $LOG_ENTERED = 0;
+}
+
+# Private helper
+sub _log_message {
# split on newlines and call log_message multiple times; saves
# the subclasses having to understand multi-line logs
my $first = 1;
- foreach my $line (split(/\n/, $message)) {
+ foreach my $line (split(/\n/, $_[1])) {
# replace control characters with "_", tabs and spaces get
# replaced with a single space.
- $line =~ tr/\x09\x20\x00-\x1f/ _/s;
+ # Deprecated here, see new Bug 7305 escaping in Logger/*.pm modules
+ #$line =~ tr/\x09\x20\x00-\x1f/ _/s;
+
if ($first) {
$first = 0;
} else {
- local $1;
$line =~ s/^([^:]+?):/$1: [...]/;
}
+
while (my ($name, $object) = each %{ $LOG_SA{method} }) {
- $object->log_message($level, $line, $now);
+ $object->log_message($_[0], $line, $_[2]);
}
}
- $LOG_ENTERED = 0;
}
=item dbg("facility: message")
@@ -273,18 +285,27 @@ sub _log {
log_message(($level == INFO ? "info" : "dbg"), $message);
}
-=item add(method => 'syslog', socket => $socket, facility => $facility)
+=item add(method => 'syslog', socket => $socket, facility => $facility, escape => $escape)
C<socket> is the type the syslog ("unix" or "inet"). C<facility> is the
-syslog facility (typically "mail").
+syslog facility (typically "mail"). If optional C<escape> is true, all
+non-ascii characters are escaped for safe output. If C<escape> is not
+defined, pre-4.0 style sanitizing is used.
+
+=item add(method => 'file', filename => $file, escape => $escape)
-=item add(method => 'file', filename => $file)
+C<filename> is the name of the log file. If optional C<escape> is true,
+escape all non-ascii characters are escaped for safe output. If C<escape>
+is not defined, pre-4.0 style sanitizing is used.
-C<filename> is the name of the log file.
+=item add(method => 'stderr', escape => $escape)
-=item add(method => 'stderr')
+No options are needed for stderr logging, just don't close stderr first. If
+optional C<escape> is true, all non-ascii characters are escaped for safe
+output. If C<escape> is not defined, pre-4.0 style sanitizing is used.
-No options are needed for stderr logging, just don't close stderr first.
+Escape method changes backslashes to \\ and non-ascii chars to \x{XX} or
+\x{XXXX} (Unicode). Pre-4.0 style is tr/\x09\x20\x00-\x1f/ _/s.
=cut
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Logger/File.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Logger/File.pm?rev=1864949&r1=1864948&r2=1864949&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Logger/File.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Logger/File.pm Mon Aug 12 09:12:40 2019
@@ -58,6 +58,7 @@ sub new {
my %params = @_;
$self->{filename} = $params{filename} || 'spamassassin.log';
$self->{timestamp_fmt} = $params{timestamp_fmt};
+ $self->{escape} = $params{escape} if exists $params{escape};
if (! $self->init()) {
die "logger: file initialization failed$eol";
@@ -101,6 +102,20 @@ sub log_message {
}
$timestamp .= ' ' if $timestamp ne '';
+ if ($self->{escape}) {
+ local $1;
+ # Bug 7305:
+ # Quote non-ascii characters as \x{XX} or \x{XXXX} (Unicode)
+ # Also quote backslash, so the log can be unescaped properly
+ $msg =~ s{([^\x20-\x5b\x5d-\x7e])}{ $1 eq '\\' ? '\\\\' :
+ sprintf(ord($1) > 255 ? '\\x{%04X}' : '\\x{%02X}', ord($1)) }egs;
+ } elsif (!exists $self->{escape}) {
+ # Backwards compatible pre-4.0 escaping, if $escape not given.
+ # replace control characters with "_", tabs and spaces get
+ # replaced with a single space.
+ $msg =~ tr/\x09\x20\x00-\x1f/ _/s;
+ }
+
my($nwrite) = syswrite(STDLOG, sprintf("%s[%s] %s: %s%s",
$timestamp, $$, $level, $msg, $eol));
defined $nwrite or warn "error writing to log file: $!";
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Logger/Stderr.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Logger/Stderr.pm?rev=1864949&r1=1864948&r2=1864949&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Logger/Stderr.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Logger/Stderr.pm Mon Aug 12 09:12:40 2019
@@ -59,6 +59,7 @@ sub new {
my %params = @_;
$self->{timestamp_fmt} = $params{timestamp_fmt};
+ $self->{escape} = $params{escape} if exists $params{escape};
return($self);
}
@@ -83,6 +84,20 @@ sub log_message {
}
$timestamp .= ' ' if $timestamp ne '';
+ if ($self->{escape}) {
+ local $1;
+ # Bug 7305:
+ # Quote non-ascii characters as \x{XX} or \x{XXXX} (Unicode)
+ # Also quote backslash, so the log can be unescaped properly
+ $msg =~ s{([^\x20-\x5b\x5d-\x7e])}{ $1 eq '\\' ? '\\\\' :
+ sprintf(ord($1) > 255 ? '\\x{%04X}' : '\\x{%02X}', ord($1)) }egs;
+ } elsif (!exists $self->{escape}) {
+ # Backwards compatible pre-4.0 escaping, if $escape not given.
+ # replace control characters with "_", tabs and spaces get
+ # replaced with a single space.
+ $msg =~ tr/\x09\x20\x00-\x1f/ _/s;
+ }
+
my($nwrite) = syswrite(STDERR, sprintf("%s[%d] %s: %s%s",
$timestamp, $$, $level, $msg, $eol));
defined $nwrite or warn "error writing to log file: $!";
Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Logger/Syslog.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Logger/Syslog.pm?rev=1864949&r1=1864948&r2=1864949&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Logger/Syslog.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Logger/Syslog.pm Mon Aug 12 09:12:40 2019
@@ -73,6 +73,7 @@ sub new {
$self->{log_socket} = $params{socket};
$self->{log_facility} = $params{facility};
$self->{timestamp_fmt} = $params{timestamp_fmt};
+ $self->{escape} = $params{escape} if exists $params{escape};
if (! $self->init()) {
die "logger: syslog initialization failed\n";
@@ -148,6 +149,20 @@ sub log_message {
$msg = '(bad prio: ' . $_[1] . ') ' . $msg;
}
+ if ($self->{escape}) {
+ local $1;
+ # Bug 7305:
+ # Quote non-ascii characters as \x{XX} or \x{XXXX} (Unicode)
+ # Also quote backslash, so the log can be unescaped properly
+ $msg =~ s{([^\x20-\x5b\x5d-\x7e])}{ $1 eq '\\' ? '\\\\' :
+ sprintf(ord($1) > 255 ? '\\x{%04X}' : '\\x{%02X}', ord($1)) }egs;
+ } elsif (!exists $self->{escape}) {
+ # Backwards compatible pre-4.0 escaping, if $escape not given
+ # replace control characters with "_", tabs and spaces get
+ # replaced with a single space.
+ $msg =~ tr/\x09\x20\x00-\x1f/ _/s;
+ }
+
# install a new handler for SIGPIPE -- this signal has been
# found to occur with syslog-ng after syslog-ng restarts.
local $SIG{'PIPE'} = sub {
Modified: spamassassin/trunk/spamd/spamd.raw
URL: http://svn.apache.org/viewvc/spamassassin/trunk/spamd/spamd.raw?rev=1864949&r1=1864948&r2=1864949&view=diff
==============================================================================
--- spamassassin/trunk/spamd/spamd.raw (original)
+++ spamassassin/trunk/spamd/spamd.raw Mon Aug 12 09:12:40 2019
@@ -462,7 +462,8 @@ if (defined $log_timestamp_fmt) {
# a nondefault timestamp format was specified, need to reopen stderr logger
Mail::SpamAssassin::Logger::remove('stderr');
Mail::SpamAssassin::Logger::add(method => 'stderr',
- timestamp_fmt => $log_timestamp_fmt);
+ timestamp_fmt => $log_timestamp_fmt,
+ escape => 1);
}
# Enable debugging, if any areas were specified. We do this already here,
@@ -602,7 +603,8 @@ if ($log_socket ne 'file' && $log_facili
socket => $log_socket,
facility => $log_facility,
ident => 'spamd',
- timestamp_fmt => $log_timestamp_fmt))
+ timestamp_fmt => $log_timestamp_fmt,
+ escape => 1))
{
# syslog method failed
$log_facility = 'stderr';
@@ -612,7 +614,8 @@ if ($log_socket ne 'file' && $log_facili
elsif ($log_facility eq 'file') {
if (!Mail::SpamAssassin::Logger::add(method => 'file',
filename => $log_file,
- timestamp_fmt => $log_timestamp_fmt))
+ timestamp_fmt => $log_timestamp_fmt,
+ escape => 1))
{
# file method failed
$log_facility = 'stderr';