1 package SL::ArchiveZipFixes;
6 use Archive::Zip::Member;
9 # Archive::Zip contains a bug starting with 1.31_04 which prohibits
10 # re-writing Zips produced by LibreOffice (.odt). See
11 # https://rt.cpan.org/Public/Bug/Display.html?id=92205
13 sub _member_writeToFileHandle {
16 my $fhIsSeekable = shift;
19 return _error("no member name given for $self")
20 if $self->fileName() eq '';
22 $self->{'writeLocalHeaderRelativeOffset'} = $offset;
23 $self->{'wasWritten'} = 0;
25 # Determine if I need to write a data descriptor
26 # I need to do this if I can't refresh the header
27 # and I don't know compressed size or crc32 fields.
28 my $headerFieldsUnknown = (
29 ( $self->uncompressedSize() > 0 )
30 and ($self->compressionMethod() == Archive::Zip::COMPRESSION_STORED
31 or $self->desiredCompressionMethod() == Archive::Zip::COMPRESSION_DEFLATED )
34 my $shouldWriteDataDescriptor =
35 ( $headerFieldsUnknown and not $fhIsSeekable );
37 $self->hasDataDescriptor(1)
38 if ($shouldWriteDataDescriptor);
40 $self->{'writeOffset'} = 0;
42 my $status = $self->rewindData();
43 ( $status = $self->_writeLocalFileHeader($fh) )
44 if $status == Archive::Zip::AZ_OK;
45 ( $status = $self->_writeData($fh) )
46 if $status == Archive::Zip::AZ_OK;
47 if ( $status == Archive::Zip::AZ_OK ) {
48 $self->{'wasWritten'} = 1;
49 if ( $self->hasDataDescriptor() ) {
50 $status = $self->_writeDataDescriptor($fh);
52 elsif ($headerFieldsUnknown) {
53 $status = $self->_refreshLocalFileHeader($fh);
60 sub fix_write_to_file_handle_1_30 {
61 return if version->new("$Archive::Zip::VERSION")->numify <= version->new("1.30")->numify;
63 no warnings 'redefine';
65 *Archive::Zip::Member::_writeToFileHandle = \&_member_writeToFileHandle;
69 fix_write_to_file_handle_1_30();