Subject: | Memory leak in Mail::SPF::MacroString |
Date: | Fri, 4 Dec 2015 14:03:18 +0800 |
To: | bug-Mail-SPF [...] rt.cpan.org |
From: | Mark Webb-Johnson <mark.johnson [...] network-box.com> |
The following example code shows a memory leak in Mail::SPF::MacroString.
#!/usr/bin/perl
use Mail::SPF;
use Net::DNS::Resolver;
my $resolver = Net::DNS::Resolver->new(retry=>3, retrans=>2);
my $engine = Mail::SPF::Server->new(dns_resolver => $resolver, max_void_dns_lookups => 2);
foreach (1 .. 100)
{
my $request = Mail::SPF::Request->new (
versions => [1,2],
scope => 'mfrom',
identity => 'joe@microsoft.com',
helo_identity => 'microsoft.com',
ip_address => '1.2.3.4'
);
my $result = $engine->process($request);
}
$engine = undef;
$resolver = undef;
use Devel::Gladiator qw(walk_arena arena_ref_counts arena_table);
foreach (split /\n/,arena_table())
{
print $_,"\n";
}
Example output is:
ARENA COUNTS:
127743 SCALAR
37991 REF
11608 REF-NetAddr::IP
10707 NetAddr::IP
9406 Mail::SPF::Mech::IP4
9406 REF-Mail::SPF::Mech::IP4
5209 ARRAY
3705 REF-Mail::SPF::Request
3063 GLOB
2902 Mail::SPF::MacroString
2902 REF-Mail::SPF::MacroString
2795 HASH
2460 REF-ARRAY
2246 REF-HASH
1904 REF-Mail::SPF::Server
1372 CODE
1001 Mail::SPF::Request
1001 Mail::SPF::v1::Record
1001 REF-Mail::SPF::v1::Record
1000 Mail::SPF::Mech::All
1000 Mail::SPF::Mech::Include
1000 REF-Mail::SPF::Mech::All
1000 REF-Mail::SPF::Mech::Include
349 REF-SCALAR
200 Mail::SPF::Mech::IP6
200 REF-Mail::SPF::Mech::IP6
81 REF-Regexp
81 Regexp
43 REF-utf8
38 REF-version
38 version
30 REF-REF
23 utf8
8 LVALUE
6 IO::Handle
6 REF-Encode::XS
4 Encode::XS
3 REF-Encode::utf8
2 Encode::utf8
2 FORMAT
2 REF-Mail::SPF::Result::Fail
1 Config
1 Encode::Internal
1 Errno
1 Mail::SPF::EInvalidRecordVersion
1 Mail::SPF::Result::Fail
1 Mail::SPF::Result::NeutralByDefault
1 Mail::SPF::Server
1 Net::DNS::Resolver
1 REF-CODE
1 REF-Config
1 REF-Encode::Internal
1 REF-Errno
1 REF-Mail::SPF::EInvalidRecordVersion
1 REF-Mail::SPF::Result::NeutralByDefault
1 REF-Net::DNS::Resolver
Issue seems to be the common perl circular reference when passing the ‘server' and ‘request' references.
An ugly patch (using Scalar::Util weaken) is:
diff -ur lib/Mail/SPF/MacroString.pm lib~/Mail/SPF/MacroString.pm
--- a/lib/Mail/SPF/MacroString.pm 2012-01-30 08:59:22.000000000 +0000
+++ b/lib/Mail/SPF/MacroString.pm 2015-12-04 05:37:43.520031685 +0000
@@ -32,6 +32,8 @@
use Mail::SPF::Util;
+use Scalar::Util 'weaken';
+
use constant TRUE => (0 == 0);
use constant FALSE => not TRUE;
@@ -135,6 +137,8 @@
$self = $self->SUPER::new(%options);
defined($self->{text})
or throw Mail::SPF::EOptionRequired("Missing required 'text' option");
+ weaken($self->{'server'});
+ weaken($self->{'request'});
return $self;
}
But, not elegant.
Regards.
Message body is not shown because it is too large.