lib/PublicInbox/Eml.pm | 18 +++++++++++------- t/eml.t | 4 ++-- diff --git a/lib/PublicInbox/Eml.pm b/lib/PublicInbox/Eml.pm index 2ccbb6597de406680376ad9a02a419ee53d1015b..ef401141c135db358861e83b7271336d9df12f20 100644 --- a/lib/PublicInbox/Eml.pm +++ b/lib/PublicInbox/Eml.pm @@ -38,9 +38,11 @@ use PublicInbox::EmlContentFoo qw(parse_content_type parse_content_disposition); $PublicInbox::EmlContentFoo::STRICT_PARAMS = 0; -our $MAXPARTS = 1000; # same as SpamAssassin -our $MAXDEPTH = 20; # seems enough, Perl sucks, here -our $MAXBOUNDLEN = 2048; # same as postfix +our $mime_parts_limit = 1000; # same as SpamAssassin (not in postfix AFAIK) + +# the rest of the limit names are taken from postfix: +our $mime_nesting_limit = 20; # seems enough, Perl sucks, here +our $mime_boundary_length_limit = 2048; # same as postfix our $header_size_limit = 102400; # same as postfix my %MIME_ENC = (qp => \&enc_qp, base64 => \&encode_base64); @@ -151,7 +153,7 @@ # TODO: descend into message/rfc822 parts (Email::MIME didn't) sub mp_descend ($$) { my ($self, $nr) = @_; # or $once for top-level my $bnd = ct($self)->{attributes}->{boundary} // return; # single-part - return if $bnd eq '' || length($bnd) >= $MAXBOUNDLEN; + return if $bnd eq '' || length($bnd) >= $mime_boundary_length_limit; $bnd = quotemeta($bnd); # "multipart" messages can exist w/o a body @@ -179,7 +181,7 @@ $$bdy, # + 3 since we don't want the last part # processed to include any other excluded # parts ($nr starts at 1, and I suck at math) - $MAXPARTS + 3 - $nr); + $mime_parts_limit + 3 - $nr); if (@parts) { # the usual path if we got this far: undef $bdy; # release memory ASAP if $nr > 0 @@ -218,13 +220,15 @@ return $cb->([$self, 0, 0], $arg); $p = [ $p, 0 ]; my @s; # our virtual stack my $nr = 0; - while ((scalar(@{$p->[0]}) || ($p = pop @s)) && ++$nr <= $MAXPARTS) { + while ((scalar(@{$p->[0]}) || ($p = pop @s)) && + ++$nr <= $mime_parts_limit) { ++$p->[-1]; # bump index my (undef, @idx) = @$p; @idx = (join('.', @idx)); my $depth = ($idx[0] =~ tr/././) + 1; my $sub = new_sub(undef, \(shift @{$p->[0]})); - if ($depth < $MAXDEPTH && (my $nxt = mp_descend($sub, $nr))) { + if ($depth < $mime_nesting_limit && + (my $nxt = mp_descend($sub, $nr))) { push(@s, $p) if scalar @{$p->[0]}; $p = [ $nxt, @idx, 0 ]; } else { # a leaf node diff --git a/t/eml.t b/t/eml.t index d5e8cbcbbbacfde4b563e2b85bfb9fda26e6e11e..c91deb3ab29a8a1a78f3a186af3188dca7b68925 100644 --- a/t/eml.t +++ b/t/eml.t @@ -282,7 +282,7 @@ my $eml = eml_load 't/psgi_attach.eml'; my @orig; $eml->each_part(sub { push @orig, $_[0]->[0] }); - local $PublicInbox::Eml::MAXPARTS = scalar(@orig); + local $PublicInbox::Eml::mime_parts_limit = scalar(@orig); my $i = 0; $eml->each_part(sub { my $cur = $_[0]->[0]; @@ -290,7 +290,7 @@ my $prv = $orig[$i++]; is($cur->body_raw, $prv->body_raw, "part #$i matches"); }); is($i, scalar(@orig), 'maxparts honored'); - $PublicInbox::Eml::MAXPARTS--; + $PublicInbox::Eml::mime_parts_limit--; my @ltd; $eml->each_part(sub { push @ltd, $_[0]->[0] }); for ($i = 0; $i <= $#ltd; $i++) {