Subject: | Fails on unseekable file handle after desiredCompressionLevel() |
Archive::Zip 1.30 fails writing to an unseekable file handle after
calling desiredCompressionLevel(). 1.23 works fine. Tested with perl
5.8.8 and 5.10.0.
Here is a test program, test.pl:
#!/usr/bin/perl
use strict;
use Archive::Zip;
use IO::Handle;
my $fh = new IO::Handle;
$fh->fdopen(fileno(STDOUT), "w");
my $zip = Archive::Zip->new();
my $fileMember = $zip->addFile("test.pl");
$fileMember->desiredCompressionLevel(5);
$zip->writeToFileHandle($fh, 0);
Running it as:
./test.pl > test.zip
fails with the error:
Can't locate object method "tell" via package "IO::Handle" at
/usr/lib/perl5/vendor_perl/5.8.8/Archive/Zip/Member.pm line 746.
The bug is that Archive::Zip::Member->bitFlag() overwrites the flags
when it is called, even with no arguments. In particular,
_writeToFileHandle() calls:
$self->hasDataDescriptor(1)
when the output is not seekable, which sets
GPBF_HAS_DATA_DESCRIPTOR_MASK in $self->{'bitFlag'}. Just after that,
_writeToFileHandle() calls _writeLocalFileHeader(), which in turn calls
$self->bitFlag(). That overwrites the GPBF_HAS_DATA_DESCRIPTOR_MASK
bit, and then _writeToFileHandle() calls _refreshLocalFileHeader()
instead of _writeDataDescriptor() because that bit was cleared.
A patch to fix it is attached, although I don't know if it is correct.
The code that sets bitFlag is only executed when bitFlag is called with
an argument. The reason I don't think it is correct is I don't see
where bitFlag(0) is called to do this initialization. Perhaps this code
should move to desiredCompressionLevel()?
Craig
Subject: | bitFlag_patch_1_30 |
Message body not shown because it is not plain text.