diff --git a/src/lib/Sympa.pm b/src/lib/Sympa.pm index 24ee44b5a..b5a86e4c5 100644 --- a/src/lib/Sympa.pm +++ b/src/lib/Sympa.pm @@ -767,16 +767,38 @@ sub is_listmaster { } # Old name: tools::get_message_id(). +# +# Note: +# The boundary of multipart message is generated based on this function +# and its length, 2 octets longer, should be limited up to 70 octets +# (See RFC 2046, 5.1.1). So as of 6.2.74, the length of the domain part will +# be limited. See also GH #1795. sub unique_message_id { my $that = shift; - my ($time, $usec) = Sympa::Tools::Time::gettimeofday(); my $domain = (ref $that eq 'Sympa::List') ? $that->{'domain'} : ($that and $that ne '*') ? $that : $Conf::Conf{'domain'}; - return sprintf '', $time, $usec, $PID, - (int rand 999), $domain; + + my ($time, $usec) = Sympa::Tools::Time::gettimeofday(); + my $base32 = sprintf '%s%s%s%s', + _base32($time, 35), _base32($usec, 20), _base32($PID, 35), + _base32(int(rand 1023), 10); + + return sprintf '', $base32, substr $domain, -39; +} + +my @base32_alphabets = split '', '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; + +sub _base32 { + my $dec = shift; + my $prc = shift; + + # Convert a (possiblly signed) decimal $dec to binary in $prc bits + # then encode it in base32. + my $vec = substr sprintf("%0${prc}b", $dec), -$prc; + return $vec =~ s/([01]{5})/$base32_alphabets[oct "0b$1"]/egr; } 1; diff --git a/src/lib/Sympa/Message/Template.pm b/src/lib/Sympa/Message/Template.pm index a9ca7b67e..f9d33a5ff 100644 --- a/src/lib/Sympa/Message/Template.pm +++ b/src/lib/Sympa/Message/Template.pm @@ -186,12 +186,13 @@ sub new { $data->{'fromlist'} = Sympa::get_address($list, 'owner'); } } + my $unique_id = Sympa::unique_message_id($robot_id); - $data->{'boundary'} = sprintf '----------=_%s', $unique_id + $data->{'boundary'} = sprintf '=_%s', $unique_id unless $data->{'boundary'}; - $data->{'boundary1'} = sprintf '---------=1_%s', $unique_id + $data->{'boundary1'} = sprintf '=1%s', $unique_id unless $data->{'boundary1'}; - $data->{'boundary2'} = sprintf '---------=2_%s', $unique_id + $data->{'boundary2'} = sprintf '=2%s', $unique_id unless $data->{'boundary2'}; my $self = $class->_new_from_template($that, $tpl . '.tt2',