From: Eric Wong Date: Sat, 16 Oct 2021 23:23:01 +0000 (+0000) Subject: eml: fix leak workaround X-Git-Tag: v1.7.0~117 X-Git-Url: http://www.git.stargrave.org/?p=public-inbox.git;a=commitdiff_plain;h=4fbec2e6737e9b65f0287ad1ebd14e20dfc10a93 eml: fix leak workaround Our previous workaround didn't actually work around the leak in since croak()-via-Perl was still invoked before the SV reference count could be decremented. Put in a proper workaround which saves warnings onto a temporary variable and only croak after ->decode or ->encode returns; not inside those methods. --- diff --git a/lib/PublicInbox/Eml.pm b/lib/PublicInbox/Eml.pm index 69c26932..3c681ba5 100644 --- a/lib/PublicInbox/Eml.pm +++ b/lib/PublicInbox/Eml.pm @@ -333,15 +333,18 @@ sub body_set { } sub body_str_set { - my ($self, $body_str) = @_; + my ($self, $str) = @_; my $cs = ct($self)->{attributes}->{charset} // croak('body_str was given, but no charset is defined'); my $enc = find_encoding($cs) // croak "unknown encoding `$cs'"; - $body_str = do { - local $SIG{__WARN__} = \&croak; - $enc->encode($body_str, Encode::FB_WARN); + my $tmp; + { + my @w; + local $SIG{__WARN__} = sub { push @w, @_ }; + $tmp = $enc->encode($str, Encode::FB_WARN); + croak(@w) if @w; }; - body_set($self, \$body_str); + body_set($self, \$tmp); } sub content_type { scalar header($_[0], 'Content-Type') } @@ -466,8 +469,11 @@ sub body_str { my $enc = find_encoding($cs) or croak "unknown encoding `$cs'"; my $tmp = body($self); # workaround https://rt.cpan.org/Public/Bug/Display.html?id=139622 - local $SIG{__WARN__} = \&croak; - $enc->decode($tmp, Encode::FB_WARN); + my @w; + local $SIG{__WARN__} = sub { push @w, @_ }; + my $ret = $enc->decode($tmp, Encode::FB_WARN); + croak(@w) if @w; + $ret; } sub as_string {