https://bz.apache.org/SpamAssassin/show_bug.cgi?id=8470
Bug ID: 8470
Summary: r1939572 regresses zip extraction to require non-core
IO::String; previously used core IO::Uncompress::Unzip
Product: Spamassassin
Version: 4.0.3
Hardware: PC
OS: Mac OS X
Status: NEW
Severity: normal
Priority: P2
Component: Libraries
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: Undefined
Created attachment 6162
--> https://bz.apache.org/SpamAssassin/attachment.cgi?id=6162&action=edit
proposed patch
r1939572 ("New size-limited unzipping utility functions that other code now
uses to unzip and unrar") introduced Mail::SpamAssassin::Util::Zip and reworked
Handler::Archive (and Plugin::OLEVBMacro) to read zip archives through it.
The new utility reads archives with Archive::Zip + IO::String, gating zip
support on both being installed:
# lib/Mail/SpamAssassin/Util/Zip.pm
use constant HAS_ARCHIVE_ZIP => eval { require Archive::Zip; 1 };
use constant HAS_IO_STRING => eval { require IO::String; 1 };
...
sub open_zip {
my ($dataref) = @_;
return unless HAS_ARCHIVE_ZIP && HAS_IO_STRING;
Before r1939572, Handler::Archive extracted zips with IO::Uncompress::Unzip,
which is part of core Perl (via IO::Compress) and needs no CPAN install:
-use constant HAS_UNZIP => eval { require IO::Uncompress::Unzip; 1 };
...
- my $u = IO::Uncompress::Unzip->new(\$data, MultiStream => 0);
So the change swaps a core-only zip path for one that depends on the non-core
IO::String. On any installation that has Archive::Zip but not IO::String, zip
extraction is now silently disabled -- the handler only emits the startup
warning:
archive: zip archives not supported, required module Archive::Zip or
IO::String missing
IO::String is the only newly-required piece; it is used solely to wrap the
in-memory archive bytes as a filehandle for Archive::Zip->readFromFileHandle().
Perl has provided an in-core equivalent since 5.8 (open my $fh, '<', \$scalar),
so the dependency is avoidable.
Impact
- Zip extraction (and anything downstream of it) stops working wherever
IO::String is absent, even though Archive::Zip is installed -- a regression
from the prior core-only behavior.
- t/handler_javascript_utf16.t fails on such hosts, because it relies on the
Archive handler extracting an inner UTF-16 .js from a zip fixture:
Not found: utf16le_bom_js_normalized = 1.0 JS_UTF16
Not found: utf16be_nobom_js_normalized = 1.0 JS_UTF16
...
t/handler_javascript_utf16.t (Wstat: 512) Tests: 7 Failed: 2 (tests 3,
5)
- t/handler_archive.t and t/olevbmacro.t do not fail but skip entirely
(skip_all => 'Need IO::String for this test'), so the regression is otherwise
invisible in `make test` on these hosts.
- r1939572 also added IO::String to Makefile.PL PREREQ_PM and
DependencyInfo.pm, so fresh installs now pull in a dependency that core Perl
already satisfied.
Steps to reproduce
On a host with Archive::Zip installed but not IO::String:
perl -MArchive::Zip -e1 # ok
perl -MIO::String -e1 # Can't locate IO/String.pm
prove t/handler_javascript_utf16.t # FAIL (2/7)
Environment where observed
- SVN trunk at/after r1939572; Mail::SpamAssassin 4.000003
- Perl v5.36.0
- Archive::Zip 1.68 present; IO::String absent; IO::Uncompress::Unzip (core)
present
Proposed fix
Keep Archive::Zip (it provides the new size-limited, joined-archive reading
that r1939572 intends) but drop the IO::String requirement, reading the
in-memory archive via an in-core scalar filehandle instead:
sub _read_zip {
my ($dataref) = @_;
open(my $fh, '<', $dataref) or return;
binmode $fh;
my $old_handler = Archive::Zip::setErrorHandler(\&_zip_error);
my $zip = Archive::Zip->new();
my $status = $zip->readFromFileHandle($fh);
Archive::Zip::setErrorHandler($old_handler);
return unless $status == Archive::Zip::AZ_OK();
return $zip;
}
and remove the HAS_IO_STRING gate from Util::Zip, Handler::Archive, and
Plugin::OLEVBMacro, the IO::String entry from Makefile.PL and
DependencyInfo.pm,
and the IO::String skip guards in t/handler_archive.t and t/olevbmacro.t.
With this change all three tests pass (no longer skipped), and zip extraction
no
longer requires any non-core module beyond Archive::Zip.
--
You are receiving this mail because:
You are the assignee for the bug.